From 693bd558eef3580eacf6f2cb3708d408981c62b9 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 27 Nov 2023 08:42:42 +0000 Subject: [PATCH 1/2] JSON.parse(): ensure jspHasError() is always checked --- src/jswrap_json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jswrap_json.c b/src/jswrap_json.c index 77c90287b1..7fcb89958d 100644 --- a/src/jswrap_json.c +++ b/src/jswrap_json.c @@ -137,7 +137,7 @@ JsVar *jswrap_json_parse_internal(JSONFlags flags) { case '{': { JsVar *obj = jsvNewObject(); if (!obj) return 0; jslGetNextToken(); // { - while (lex->tk == LEX_STR || lex->tk == LEX_ID && !jspHasError()) { + while ((lex->tk == LEX_STR || lex->tk == LEX_ID) && !jspHasError()) { if (!(flags&JSON_DROP_QUOTES)) { jslMatch(LEX_STR); return obj; From 4dd95bfd5e5920f923e64b970dfb1132f2ff8e75 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 27 Nov 2023 08:43:28 +0000 Subject: [PATCH 2/2] JSON.parse(): bail if we don't get a string key (in non-relaxed mode) --- src/jswrap_json.c | 6 +++--- tests/test_json_object.js | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/jswrap_json.c b/src/jswrap_json.c index 7fcb89958d..336d44f036 100644 --- a/src/jswrap_json.c +++ b/src/jswrap_json.c @@ -138,9 +138,9 @@ JsVar *jswrap_json_parse_internal(JSONFlags flags) { JsVar *obj = jsvNewObject(); if (!obj) return 0; jslGetNextToken(); // { while ((lex->tk == LEX_STR || lex->tk == LEX_ID) && !jspHasError()) { - if (!(flags&JSON_DROP_QUOTES)) { - jslMatch(LEX_STR); - return obj; + if (!(flags&JSON_DROP_QUOTES) && !jslMatch(LEX_STR)) { + jsvUnLock(obj); + return 0; } JsVar *key = jsvAsArrayIndexAndUnLock(jslGetTokenValueAsVar()); jslGetNextToken(); diff --git a/tests/test_json_object.js b/tests/test_json_object.js index 604ae427f3..4eb752f913 100644 --- a/tests/test_json_object.js +++ b/tests/test_json_object.js @@ -1,6 +1,27 @@ // JSON shouldn't print stuff like __proto__ and constructor -function A() {} +function A() {} var a = new A(); result = JSON.stringify(a)=="{}"; + +function assertEq(got, expected) { + if (typeof got !== typeof expected) + throw new Error("mismatch, " + typeof got + " != " + typeof expected); + + if (typeof got === "object") + // note: doesn't check keys in `got` + for (var k in expected) + assertEq(got[k], expected[k]); + else if (got !== expected) + throw new Error("mismatch, " + got + " != " + expected); +} + +// no exceptions thrown: +assertEq(JSON.parse('{"a": 1}'), {"a": 1}); +assertEq(JSON.parse('["4", 5, "six"]'), ["4", 5, "six"]); +assertEq(JSON.parse('["4", 5, "six", {"x": 5}]'), ["4", 5, "six", {"x": 5}]); +assertEq(JSON.parse('""'), ""); +assertEq(JSON.parse('5'), 5); +assertEq(JSON.parse('[]'), []); +assertEq(JSON.parse('{}'), {});