commit 317375877576b10fd5312a7b0dec4a192881eead Author: Gary E. Miller <gem@rellim.com> Date: Thu Jun 14 19:01:18 2018 -0700 json.c be sure a string is NUL terminated. diff --git a/json.c b/json.c index 0f912c4a1..6f444c183 100644 --- a/json.c +++ b/json.c @@ -394,6 +394,7 @@ static int json_internal_read_object(const char *cp, case 'u': for (n = 0; n < 4 && cp[n] != '\0'; n++) uescape[n] = *cp++; + uescape[n] = '\0'; /* terminate */ --cp; (void)sscanf(uescape, "%04x", &u); *pval++ = (char)u; /* will truncate values above 0xff */ commit 9b3724cb7bca7a0776bcb9b054cd1d8d736278a4 Author: Gary E. Miller <gem@rellim.com> Date: Thu Jun 14 19:21:36 2018 -0700 json.c: Fail on bad escape string. diff --git a/json.c b/json.c index 6f444c183..5c4dd3de0 100644 --- a/json.c +++ b/json.c @@ -396,8 +396,9 @@ static int json_internal_read_object(const char *cp, uescape[n] = *cp++; uescape[n] = '\0'; /* terminate */ --cp; - (void)sscanf(uescape, "%04x", &u); - *pval++ = (char)u; /* will truncate values above 0xff */ + if (1 != sscanf(uescape, "%4x", &u)) + return JSON_ERR_BADSTRING; + *pval++ = (char)u; /* will truncate values above 0xff */ break; default: /* handles double quote and solidus */ *pval++ = *cp; commit a968ebb3842be50ceef9862a786f0784b2324cd5 Author: Gary E. Miller <gem@rellim.com> Date: Thu Jun 14 20:31:18 2018 -0700 json.c Allow for \u escapes with fewer than 4 digits. \u0, \u00, \u000 and \u000. The next charbetter be non-hex. diff --git a/json.c b/json.c index 5c4dd3de0..81a3bac50 100644 --- a/json.c +++ b/json.c @@ -392,12 +392,14 @@ static int json_internal_read_object(const char *cp, *pval++ = '\t'; break; case 'u': - for (n = 0; n < 4 && cp[n] != '\0'; n++) + cp++; /* skip the 'u' */ + for (n = 0; n < 4 && isxdigit(*cp); n++) uescape[n] = *cp++; - uescape[n] = '\0'; /* terminate */ + uescape[n] = '\0'; /* terminate */ --cp; - if (1 != sscanf(uescape, "%4x", &u)) + if (1 != sscanf(uescape, "%4x", &u)) { return JSON_ERR_BADSTRING; + } *pval++ = (char)u; /* will truncate values above 0xff */ break; default: /* handles double quote and solidus */ commit 7646cbd04055a50b157312ba6b376e88bd398c19 Author: Eric S. Raymond <esr@thyrsus.com> Date: Fri Jun 15 13:26:28 2018 -0400 Add bounds check in in_escape state of JSON parser. diff --git a/json.c b/json.c index c97fd161d..1d3c4cd9c 100644 --- a/json.c +++ b/json.c @@ -375,6 +375,12 @@ static int json_internal_read_object(const char *cp, if (pval == NULL) /* don't update end here, leave at value start */ return JSON_ERR_NULLPTR; + else if (pval > valbuf + JSON_VAL_MAX - 1 + || pval > valbuf + maxlen) { + json_debug_trace((1, "String value too long.\n")); + /* don't update end here, leave at value start */ + return JSON_ERR_STRLONG; /* */ + } switch (*cp) { case 'b': *pval++ = '\b'; @@ -400,7 +406,7 @@ static int json_internal_read_object(const char *cp, if (1 != sscanf(uescape, "%4x", &u)) { return JSON_ERR_BADSTRING; } - *pval++ = (char)u; /* will truncate values above 0xff */ + *pval++ = (unsigned char)u; /* will truncate values above 0xff */ break; default: /* handles double quote and solidus */ *pval++ = *cp; commit a399e85c1201400e281f2c1dc29dde21c29b0088 Author: Gary E. Miller <gem@rellim.com> Date: Fri Jun 15 11:30:04 2018 -0700 json.c: ECMA-404 says JSON \u must have 4 hex digits ECMA-404 says \u generates UNICODE, but json.c limits it to latin1 (0 to 0xff). diff --git a/json.c b/json.c index 1d3c4cd9c..ab1fa4065 100644 --- a/json.c +++ b/json.c @@ -403,10 +403,11 @@ static int json_internal_read_object(const char *cp, uescape[n] = *cp++; uescape[n] = '\0'; /* terminate */ --cp; - if (1 != sscanf(uescape, "%4x", &u)) { + /* ECMA-404 says JSON \u must have 4 hex digits */ + if ((4 != n) || (1 != sscanf(uescape, "%4x", &u))) { return JSON_ERR_BADSTRING; } - *pval++ = (unsigned char)u; /* will truncate values above 0xff */ + *pval++ = (unsigned char)u; /* truncate values above 0xff */ break; default: /* handles double quote and solidus */ *pval++ = *cp;