diff --git a/mozilla/dom/src/json/nsJSON.cpp b/mozilla/dom/src/json/nsJSON.cpp index 93e3190a52f..83e3aebbf4f 100644 --- a/mozilla/dom/src/json/nsJSON.cpp +++ b/mozilla/dom/src/json/nsJSON.cpp @@ -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 } diff --git a/mozilla/dom/src/json/nsJSON.h b/mozilla/dom/src/json/nsJSON.h index 20ab7d60e36..2995b51271a 100644 --- a/mozilla/dom/src/json/nsJSON.h +++ b/mozilla/dom/src/json/nsJSON.h @@ -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, diff --git a/mozilla/dom/src/json/test/fail1.json b/mozilla/dom/src/json/test/fail1.json new file mode 100644 index 00000000000..6216b865f10 --- /dev/null +++ b/mozilla/dom/src/json/test/fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail10.json b/mozilla/dom/src/json/test/fail10.json new file mode 100644 index 00000000000..5d8c0047bd5 --- /dev/null +++ b/mozilla/dom/src/json/test/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail11.json b/mozilla/dom/src/json/test/fail11.json new file mode 100644 index 00000000000..76eb95b4583 --- /dev/null +++ b/mozilla/dom/src/json/test/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail12.json b/mozilla/dom/src/json/test/fail12.json new file mode 100644 index 00000000000..77580a4522d --- /dev/null +++ b/mozilla/dom/src/json/test/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail13.json b/mozilla/dom/src/json/test/fail13.json new file mode 100644 index 00000000000..379406b59bd --- /dev/null +++ b/mozilla/dom/src/json/test/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail14.json b/mozilla/dom/src/json/test/fail14.json new file mode 100644 index 00000000000..0ed366b38a3 --- /dev/null +++ b/mozilla/dom/src/json/test/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail15.json b/mozilla/dom/src/json/test/fail15.json new file mode 100644 index 00000000000..fc8376b605d --- /dev/null +++ b/mozilla/dom/src/json/test/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail16.json b/mozilla/dom/src/json/test/fail16.json new file mode 100644 index 00000000000..3fe21d4b532 --- /dev/null +++ b/mozilla/dom/src/json/test/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail17.json b/mozilla/dom/src/json/test/fail17.json new file mode 100644 index 00000000000..62b9214aeda --- /dev/null +++ b/mozilla/dom/src/json/test/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail18.json b/mozilla/dom/src/json/test/fail18.json new file mode 100644 index 00000000000..edac92716f1 --- /dev/null +++ b/mozilla/dom/src/json/test/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail19.json b/mozilla/dom/src/json/test/fail19.json new file mode 100644 index 00000000000..3b9c46fa9a2 --- /dev/null +++ b/mozilla/dom/src/json/test/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail2.json b/mozilla/dom/src/json/test/fail2.json new file mode 100644 index 00000000000..6b7c11e5a56 --- /dev/null +++ b/mozilla/dom/src/json/test/fail2.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail20.json b/mozilla/dom/src/json/test/fail20.json new file mode 100644 index 00000000000..27c1af3e72e --- /dev/null +++ b/mozilla/dom/src/json/test/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail21.json b/mozilla/dom/src/json/test/fail21.json new file mode 100644 index 00000000000..62474573b21 --- /dev/null +++ b/mozilla/dom/src/json/test/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail22.json b/mozilla/dom/src/json/test/fail22.json new file mode 100644 index 00000000000..a7752581bcf --- /dev/null +++ b/mozilla/dom/src/json/test/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail23.json b/mozilla/dom/src/json/test/fail23.json new file mode 100644 index 00000000000..494add1ca19 --- /dev/null +++ b/mozilla/dom/src/json/test/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail24.json b/mozilla/dom/src/json/test/fail24.json new file mode 100644 index 00000000000..caff239bfc3 --- /dev/null +++ b/mozilla/dom/src/json/test/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail25.json b/mozilla/dom/src/json/test/fail25.json new file mode 100644 index 00000000000..8b7ad23e010 --- /dev/null +++ b/mozilla/dom/src/json/test/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail26.json b/mozilla/dom/src/json/test/fail26.json new file mode 100644 index 00000000000..845d26a6a54 --- /dev/null +++ b/mozilla/dom/src/json/test/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail27.json b/mozilla/dom/src/json/test/fail27.json new file mode 100644 index 00000000000..6b01a2ca4a9 --- /dev/null +++ b/mozilla/dom/src/json/test/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail28.json b/mozilla/dom/src/json/test/fail28.json new file mode 100644 index 00000000000..621a0101c66 --- /dev/null +++ b/mozilla/dom/src/json/test/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail29.json b/mozilla/dom/src/json/test/fail29.json new file mode 100644 index 00000000000..47ec421bb62 --- /dev/null +++ b/mozilla/dom/src/json/test/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail3.json b/mozilla/dom/src/json/test/fail3.json new file mode 100644 index 00000000000..168c81eb785 --- /dev/null +++ b/mozilla/dom/src/json/test/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail30.json b/mozilla/dom/src/json/test/fail30.json new file mode 100644 index 00000000000..8ab0bc4b8b2 --- /dev/null +++ b/mozilla/dom/src/json/test/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail31.json b/mozilla/dom/src/json/test/fail31.json new file mode 100644 index 00000000000..1cce602b518 --- /dev/null +++ b/mozilla/dom/src/json/test/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail32.json b/mozilla/dom/src/json/test/fail32.json new file mode 100644 index 00000000000..45cba7396ff --- /dev/null +++ b/mozilla/dom/src/json/test/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail33.json b/mozilla/dom/src/json/test/fail33.json new file mode 100644 index 00000000000..ca5eb19dc97 --- /dev/null +++ b/mozilla/dom/src/json/test/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail34.json b/mozilla/dom/src/json/test/fail34.json new file mode 100644 index 00000000000..f7f40b9f6d8 --- /dev/null +++ b/mozilla/dom/src/json/test/fail34.json @@ -0,0 +1 @@ +0{ \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail4.json b/mozilla/dom/src/json/test/fail4.json new file mode 100644 index 00000000000..9de168bf34e --- /dev/null +++ b/mozilla/dom/src/json/test/fail4.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail5.json b/mozilla/dom/src/json/test/fail5.json new file mode 100644 index 00000000000..ddf3ce3d240 --- /dev/null +++ b/mozilla/dom/src/json/test/fail5.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail6.json b/mozilla/dom/src/json/test/fail6.json new file mode 100644 index 00000000000..ed91580e1b1 --- /dev/null +++ b/mozilla/dom/src/json/test/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail7.json b/mozilla/dom/src/json/test/fail7.json new file mode 100644 index 00000000000..8a96af3e4ee --- /dev/null +++ b/mozilla/dom/src/json/test/fail7.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail8.json b/mozilla/dom/src/json/test/fail8.json new file mode 100644 index 00000000000..b28479c6ecb --- /dev/null +++ b/mozilla/dom/src/json/test/fail8.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/mozilla/dom/src/json/test/fail9.json b/mozilla/dom/src/json/test/fail9.json new file mode 100644 index 00000000000..5815574f363 --- /dev/null +++ b/mozilla/dom/src/json/test/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/mozilla/dom/src/json/test/unit/test_decode.js b/mozilla/dom/src/json/test/unit/test_decode.js index 1d4d284c729..61b3fe74163 100644 --- a/mozilla/dom/src/json/test/unit/test_decode.js +++ b/mozilla/dom/src/json/test/unit/test_decode.js @@ -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() {