Bug 424035. Crash [@ JS_IsArrayObject] when trying to decode a bogus JSON string. r=shaver

git-svn-id: svn://10.0.0.236/trunk@248309 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
sayrer%gmail.com
2008-03-20 20:34:39 +00:00
parent e9b8a89f91
commit 6f27c1ca0b
37 changed files with 111 additions and 23 deletions

View File

@@ -936,7 +936,7 @@ buf[bufIndex] = _c; \
bufIndex++;
if (*mStatep == JSON_PARSE_STATE_INIT) {
PushState(JSON_PARSE_STATE_VALUE);
PushState(JSON_PARSE_STATE_OBJECT_VALUE);
}
for (i = 0; i < len; i++) {
@@ -944,6 +944,35 @@ bufIndex++;
switch (*mStatep) {
case JSON_PARSE_STATE_VALUE :
if (c == ']') {
// empty array
rv = PopState();
NS_ENSURE_SUCCESS(rv, rv);
if (*mStatep != JSON_PARSE_STATE_ARRAY) {
return NS_ERROR_FAILURE; // unexpected char
}
rv = this->CloseArray();
NS_ENSURE_SUCCESS(rv, rv);
rv = PopState();
NS_ENSURE_SUCCESS(rv, rv);
break;
} else if (c == '}') {
// we should only find these in OBJECT_KEY state
return NS_ERROR_FAILURE; // unexpected failure
} else if (c == '"') {
*mStatep = JSON_PARSE_STATE_STRING;
break;
} else if (IsNumChar(c)) {
*mStatep = JSON_PARSE_STATE_NUMBER;
PUSHCHAR(c);
break;
} else if (NS_IsAsciiAlpha(c)) {
*mStatep = JSON_PARSE_STATE_KEYWORD;
PUSHCHAR(c);
break;
}
// fall through in case the value is an object or array
case JSON_PARSE_STATE_OBJECT_VALUE :
if (c == '{') {
*mStatep = JSON_PARSE_STATE_OBJECT;
rv = this->OpenObject();
@@ -956,28 +985,6 @@ bufIndex++;
NS_ENSURE_SUCCESS(rv, rv);
rv = PushState(JSON_PARSE_STATE_VALUE);
NS_ENSURE_SUCCESS(rv, rv);
} else if (c == ']') {
// empty array
rv = PopState();
NS_ENSURE_SUCCESS(rv, rv);
if (*mStatep != JSON_PARSE_STATE_ARRAY) {
return NS_ERROR_FAILURE; // unexpected char
}
rv = this->CloseArray();
NS_ENSURE_SUCCESS(rv, rv);
rv = PopState();
NS_ENSURE_SUCCESS(rv, rv);
} else if (c == '}') {
// we should only find these in OBJECT_KEY state
return NS_ERROR_FAILURE; // unexpected failure
} else if (c == '"') {
*mStatep = JSON_PARSE_STATE_STRING;
} else if (IsNumChar(c)) {
*mStatep = JSON_PARSE_STATE_NUMBER;
PUSHCHAR(c);
} else if (NS_IsAsciiAlpha(c)) {
*mStatep = JSON_PARSE_STATE_KEYWORD;
PUSHCHAR(c);
} else if (!NS_IsAsciiWhitespace(c)) {
return NS_ERROR_FAILURE; // unexpected
}

View File

@@ -104,6 +104,7 @@ NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult);
enum JSONParserState {
JSON_PARSE_STATE_INIT,
JSON_PARSE_STATE_OBJECT_VALUE,
JSON_PARSE_STATE_VALUE,
JSON_PARSE_STATE_OBJECT,
JSON_PARSE_STATE_OBJECT_PAIR,

View File

@@ -0,0 +1 @@
"A JSON payload should be an object or array, not a string."

View File

@@ -0,0 +1 @@
{"Extra value after close": true} "misplaced quoted value"

View File

@@ -0,0 +1 @@
{"Illegal expression": 1 + 2}

View File

@@ -0,0 +1 @@
{"Illegal invocation": alert()}

View File

@@ -0,0 +1 @@
{"Numbers cannot have leading zeroes": 013}

View File

@@ -0,0 +1 @@
{"Numbers cannot be hex": 0x14}

View File

@@ -0,0 +1 @@
["Illegal backslash escape: \x15"]

View File

@@ -0,0 +1 @@
[\naked]

View File

@@ -0,0 +1 @@
["Illegal backslash escape: \017"]

View File

@@ -0,0 +1 @@
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]

View File

@@ -0,0 +1 @@
{"Missing colon" null}

View File

@@ -0,0 +1 @@
["Unclosed array"

View File

@@ -0,0 +1 @@
{"Double colon":: null}

View File

@@ -0,0 +1 @@
{"Comma instead of colon", null}

View File

@@ -0,0 +1 @@
["Colon instead of comma": false]

View File

@@ -0,0 +1 @@
["Bad value", truth]

View File

@@ -0,0 +1 @@
['single quote']

View File

@@ -0,0 +1 @@
[" tab character in string "]

View File

@@ -0,0 +1 @@
["tab\ character\ in\ string\ "]

View File

@@ -0,0 +1,2 @@
["line
break"]

View File

@@ -0,0 +1,2 @@
["line\
break"]

View File

@@ -0,0 +1 @@
[0e]

View File

@@ -0,0 +1 @@
{unquoted_key: "keys must be quoted"}

View File

@@ -0,0 +1 @@
[0e+]

View File

@@ -0,0 +1 @@
[0e+-1]

View File

@@ -0,0 +1 @@
{"Comma instead if closing brace": true,

View File

@@ -0,0 +1 @@
["mismatch"}

View File

@@ -0,0 +1 @@
0{

View File

@@ -0,0 +1 @@
["extra comma",]

View File

@@ -0,0 +1 @@
["double extra comma",,]

View File

@@ -0,0 +1 @@
[ , "<-- missing value"]

View File

@@ -0,0 +1 @@
["Comma after the close"],

View File

@@ -0,0 +1 @@
["Extra close"]]

View File

@@ -0,0 +1 @@
{"Extra comma": true,}

View File

@@ -153,6 +153,50 @@ function test_files() {
do_check_eq(x[17], 2e+00);
do_check_eq(x[18], 2e-00);
do_check_eq(x[19], "rosebud");
// test invalid input
//
// We allow some minor JSON infractions, like trailing commas
// Those are special-cased below, leaving the original sequence
// of failure's from Crockford intact.
//
// Section 4 of RFC 4627 allows this tolerance.
//
for (var i = 1; i <= 34; ++i) {
var path = "/dom/src/json/test/fail" + i + ".json";
try {
dump(path +"\n");
x = read_file(path);
if (i == 4) {
// ["extra comma",]
do_check_eq(x[0], "extra comma");
do_check_eq(x.length, 1);
} else if (i == 9) {
// {"Extra comma": true,}
do_check_eq(x["Extra comma"], true);
} else if (i == 13) {
// {"Numbers cannot have leading zeroes": 013}
do_check_eq(x["Numbers cannot have leading zeroes"], 13);
} else if (i == 18) {
// [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
var t = x[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0];
do_check_eq(t, "Too deep");
} else if (i == 25) {
// [" tab character in string "]
do_check_eq(x[0], "\ttab\tcharacter\tin\tstring\t");
} else if (i == 27) {
do_check_eq(x[0], "line\nbreak");
} else {
do_throw("UNREACHED");
}
} catch (ex) {
// expected from parsing invalid JSON
}
}
}
function run_test() {