/*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static void json_parser_input(struct json_parser *, struct json_token *);
static void json_error(struct json_parser *p, const char *format, ...)
- PRINTF_FORMAT(2, 3);
+ OVS_PRINTF_FORMAT(2, 3);
\f
const char *
json_type_to_string(enum json_type type)
break;
case JSON_N_TYPES:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
free(json);
}
case JSON_N_TYPES:
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
basis = hash_string(node->name, basis);
basis = json_hash(node->data, basis);
}
+ free(nodes);
return basis;
}
case JSON_N_TYPES:
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
case JSON_N_TYPES:
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
\f
significand = 0;
if (*cp == '0') {
cp++;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char) *cp)) {
json_error(p, "leading zeros not allowed");
return;
}
- } else if (isdigit(*cp)) {
+ } else if (isdigit((unsigned char) *cp)) {
do {
if (significand <= ULLONG_MAX / 10) {
significand = significand * 10 + (*cp - '0');
}
}
cp++;
- } while (isdigit(*cp));
+ } while (isdigit((unsigned char) *cp));
} else {
json_error(p, "'-' must be followed by digit");
return;
/* Optional fraction. */
if (*cp == '.') {
cp++;
- if (!isdigit(*cp)) {
+ if (!isdigit((unsigned char) *cp)) {
json_error(p, "decimal point must be followed by digit");
return;
}
imprecise = true;
}
cp++;
- } while (isdigit(*cp));
+ } while (isdigit((unsigned char) *cp));
}
/* Optional exponent. */
cp++;
}
- if (!isdigit(*cp)) {
+ if (!isdigit((unsigned char) *cp)) {
json_error(p, "exponent must contain at least one digit");
return;
}
}
exponent = exponent * 10 + (*cp - '0');
cp++;
- } while (isdigit(*cp));
+ } while (isdigit((unsigned char) *cp));
if (negative_exponent) {
pow10 -= exponent;
json_lex_4hex(const char *cp, const char *end, int *valuep)
{
unsigned int value;
+ bool ok;
if (cp + 4 > end) {
return "quoted string ends within \\u escape";
}
- value = hexits_value(cp, 4, NULL);
- if (value == UINT_MAX) {
+ value = hexits_value(cp, 4, &ok);
+ if (!ok) {
return "malformed \\u escape";
}
if (!value) {
ds_init(&out);
ds_reserve(&out, in_len);
- if (in_len > 0 && in[in_len - 1] == '\\') {
- ds_put_cstr(&out, "quoted string may not end with backslash");
- goto exit;
- }
while (in < end) {
if (*in == '"') {
ds_clear(&out);
}
in++;
+ if (in >= end) {
+ /* The JSON parser will never trigger this message, because its
+ * lexer will never pass in a string that ends in a single
+ * backslash, but json_string_unescape() has other callers that
+ * are not as careful.*/
+ ds_put_cstr(&out, "quoted string may not end with backslash");
+ goto exit;
+ }
switch (*in++) {
case '"': case '\\': case '/':
ds_put_char(&out, in[-1]);
stream = fopen(file_name, "r");
if (!stream) {
return json_string_create_nocopy(
- xasprintf("error opening \"%s\": %s", file_name, strerror(errno)));
+ xasprintf("error opening \"%s\": %s", file_name,
+ ovs_strerror(errno)));
}
json = json_from_stream(stream);
fclose(stream);
if (ferror(stream)) {
json_destroy(json);
json = json_string_create_nocopy(
- xasprintf("error reading JSON stream: %s", strerror(errno)));
+ xasprintf("error reading JSON stream: %s", ovs_strerror(errno)));
}
return json;
} else if (node->json->type == JSON_ARRAY) {
json_array_add(node->json, value);
} else {
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
} else if (node->json->type == JSON_OBJECT) {
p->parse_state = JSON_PARSE_OBJECT_NEXT;
} else {
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
}
case JSON_N_TYPES:
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}