failure. The function +json_error_string()+ maps error codes to
explanatory messages.
+When an error is returned and the end pointer argument
+is non-null, it is filled with the value of the buffer
+pointer at the time the error was thrown.
== BUGS ==
A backslash escape of "\0000" in a string value will drop a NUL in the
string that is likely to confuse C code looking at the storage. In
else {
json_debug_trace((1,
"Non-WS when expecting object start.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_OBSTART;
}
break;
break;
else {
json_debug_trace((1, "Non-WS when expecting attribute.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_ATTRSTART;
}
break;
case in_attr:
- if (pattr == NULL)
+ if (pattr == NULL) {
+ if (end)
+ *end = cp;
return JSON_ERR_NULLPTR;
+ }
if (*cp == '"') {
*pattr++ = '\0';
json_debug_trace((1, "Collected attribute name %s\n",
pval = valbuf;
} else if (pattr >= attrbuf + JSON_ATTR_MAX - 1) {
json_debug_trace((1, "Attribute name too long.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_ATTRLEN;
} else
*pattr++ = *cp;
if (cursor->type != t_array) {
json_debug_trace((1,
"Saw [ when not expecting array.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_NOARRAY;
}
substatus = json_read_array(cp, &cursor->addr.array, &cp);
} else if (cursor->type == t_array) {
json_debug_trace((1,
"Array element was specified, but no [.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_NOBRAK;
} else if (*cp == '"') {
value_quoted = true;
}
break;
case in_val_string:
- if (pval == NULL)
+ if (pval == NULL) {
+ if (end)
+ *end = cp;
return JSON_ERR_NULLPTR;
+ }
if (*cp == '\\')
state = in_escape;
else if (*cp == '"') {
} else if (pval > valbuf + JSON_VAL_MAX - 1
|| pval > valbuf + maxlen) {
json_debug_trace((1, "String value too long.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_STRLONG; /* */
} else
*pval++ = *cp;
break;
case in_escape:
- if (pval == NULL)
+ if (pval == NULL) {
+ if (end)
+ *end = cp;
return JSON_ERR_NULLPTR;
+ }
switch (*cp) {
case 'b':
*pval++ = '\b';
state = in_val_string;
break;
case in_val_token:
- if (pval == NULL)
+ if (pval == NULL) {
+ if (end)
+ *end = cp;
return JSON_ERR_NULLPTR;
+ }
if (isspace((unsigned char) *cp) || *cp == ',' || *cp == '}') {
*pval = '\0';
json_debug_trace((1, "Collected token value %s.\n", valbuf));
--cp;
} else if (pval > valbuf + JSON_VAL_MAX - 1) {
json_debug_trace((1, "Token value too long.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_TOKLONG;
} else
*pval++ = *cp;
&& cursor->type != t_ignore && cursor->map == 0)) {
json_debug_trace((1,
"Saw quoted value when expecting non-string.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_QNONSTRING;
}
if (!value_quoted
|| cursor->map != 0)) {
json_debug_trace((1,
"Didn't see quoted value when expecting string.\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_NONQSTRING;
}
if (cursor->map != 0) {
}
json_debug_trace((1, "Invalid enumerated value string %s.\n",
valbuf));
+ if (end)
+ *end = cp;
return JSON_ERR_BADENUM;
foundit:
(void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value);
}
break;
case t_character:
- if (strlen(valbuf) > 1)
+ if (strlen(valbuf) > 1) {
+ if (end)
+ *end = cp;
return JSON_ERR_STRLONG;
+ }
else
lptr[0] = valbuf[0];
break;
json_debug_trace((1,
"Required attribute value %s not present.\n",
cursor->dflt.check));
+ if (end)
+ *end = cp;
return JSON_ERR_CHECKFAIL;
}
break;
goto good_parse;
} else {
json_debug_trace((1, "Garbage while expecting comma or }\n"));
+ if (end)
+ *end = cp;
return JSON_ERR_BADTRAIL;
}
break;