From f913458884fd71b069bf4d1b084e0e94024a6d4c Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Thu, 28 Mar 2024 08:51:52 +0100 Subject: [PATCH 1/2] Fix strict name conformity cases - reject *future strict reserved words* in `js_parse_function_check_names()`. - add tests for reserved names in tests/test_language.js - change error message for `Object.create` invalid property descriptor - disable v8 test cases for deprecated legacy RegExp static properties and invalid left hand side error type - update v8.txt - fix v8.sh behavior for single tests --- quickjs.c | 26 +++- tests/test_language.js | 51 ++++++- v8.js | 11 ++ v8.sh | 10 +- v8.txt | 324 ----------------------------------------- 5 files changed, 86 insertions(+), 336 deletions(-) diff --git a/quickjs.c b/quickjs.c index 402f8f088..869806787 100644 --- a/quickjs.c +++ b/quickjs.c @@ -31466,6 +31466,25 @@ static __exception int js_parse_directives(JSParseState *s) return js_parse_seek_token(s, &pos); } +static BOOL js_invalid_strict_name(JSAtom name) { + switch (name) { + case JS_ATOM_eval: + case JS_ATOM_arguments: + case JS_ATOM_implements: // future strict reserved words + case JS_ATOM_interface: + case JS_ATOM_let: + case JS_ATOM_package: + case JS_ATOM_private: + case JS_ATOM_protected: + case JS_ATOM_public: + case JS_ATOM_static: + case JS_ATOM_yield: + return TRUE; + default: + return FALSE; + } +} + static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd, JSAtom func_name) { @@ -31476,13 +31495,12 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd, if (!fd->has_simple_parameter_list && fd->has_use_strict) { return js_parse_error(s, "\"use strict\" not allowed in function with default or destructuring parameter"); } - if (func_name == JS_ATOM_eval || func_name == JS_ATOM_arguments) { + if (js_invalid_strict_name(func_name)) { return js_parse_error(s, "invalid function name in strict code"); } for (idx = 0; idx < fd->arg_count; idx++) { name = fd->args[idx].var_name; - - if (name == JS_ATOM_eval || name == JS_ATOM_arguments) { + if (js_invalid_strict_name(name)) { return js_parse_error(s, "invalid argument name in strict code"); } } @@ -34950,7 +34968,7 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, } if ((flags & (JS_PROP_HAS_SET | JS_PROP_HAS_GET)) && (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE))) { - JS_ThrowTypeError(ctx, "cannot have setter/getter and value or writable"); + JS_ThrowTypeError(ctx, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute"); goto fail; } d->flags = flags; diff --git a/tests/test_language.js b/tests/test_language.js index b6ce4e49c..e1c098327 100644 --- a/tests/test_language.js +++ b/tests/test_language.js @@ -10,24 +10,25 @@ function assert(actual, expected, message) { && actual.toString() === expected.toString()) return; + var msg = message ? " (" + message + ")" : ""; throw Error("assertion failed: got |" + actual + "|" + - ", expected |" + expected + "|" + - (message ? " (" + message + ")" : "")); + ", expected |" + expected + "|" + msg); } -function assert_throws(expected_error, func) +function assert_throws(expected_error, func, message) { var err = false; + var msg = message ? " (" + message + ")" : ""; try { func(); } catch(e) { err = true; if (!(e instanceof expected_error)) { - throw Error("unexpected exception type"); + throw Error(`expected ${expected_error.name}, got ${e.name}${msg}`); } } if (!err) { - throw Error("expected exception"); + throw Error(`expected ${expected_error.name}${msg}`); } } @@ -536,6 +537,45 @@ function test_function_expr_name() assert_throws(TypeError, f); } +function test_name(name, err) +{ + var s1 = `(function() { var ${name}; ${name} = 1; return ${name}; })()`; + assert(1, eval(s1), `for ${s1}`); + var s1 = `(function(${name}) { ${name} = 1; return ${name}; })()`; + assert(1, eval(s1), `for ${s1}`); + var s1 = `(function ${name}() { return ${name} ? 1 : 0; })()`; + assert(1, eval(s1), `for ${s1}`); + var s2 = `"use strict"; (function() { var ${name}; ${name} = 1; return ${name}; })()`; + if (err) + assert_throws(err, () => eval(s2), `for ${s2}`); + else + assert(1, eval(s2)); + var s2 = `"use strict"; (function(${name}) { ${name} = 1; return ${name}; })()`; + if (err) + assert_throws(err, () => eval(s2), `for ${s2}`); + else + assert(1, eval(s2)); + var s2 = `"use strict"; (function ${name}() { return ${name} ? 1 : 0; })()`; + if (err) + assert_throws(err, () => eval(s2), `for ${s2}`); + else + assert(1, eval(s2)); +} + +function test_reserved_names() +{ + test_name('await'); + test_name('yield', SyntaxError); + test_name('implements', SyntaxError); + test_name('interface', SyntaxError); + test_name('let', SyntaxError); + test_name('package', SyntaxError); + test_name('private', SyntaxError); + test_name('protected', SyntaxError); + test_name('public', SyntaxError); + test_name('static', SyntaxError); +} + test_op1(); test_cvt(); test_eq(); @@ -555,3 +595,4 @@ test_spread(); test_function_length(); test_argument_scope(); test_function_expr_name(); +test_reserved_names(); diff --git a/v8.js b/v8.js index 3da78ea87..34ab65b44 100644 --- a/v8.js +++ b/v8.js @@ -15,11 +15,22 @@ const exclude = [ "disallow-codegen-from-strings.js", // --disallow-code-generation-from-strings "cyclic-array-to-string.js", // unstable output due to stack overflow "error-tostring.js", // unstable output due to stack overflow + "invalid-lhs.js", // v8 expects ReferenceError but ECMA says SyntaxError "regexp.js", // invalid, legitimate early SyntaxError "regexp-capture-3.js", // slow + "regexp-cache-replace.js", // deprecated RegExp.$1 etc. "regexp-indexof.js", // deprecated RegExp.lastMatch etc. "regexp-static.js", // deprecated RegExp static properties. + "regexp-modifiers-autogenerated-i18n.js", // invalid group + "regexp-modifiers-autogenerated.js", // invalid group + "regexp-modifiers-dotall.js", // invalid group + "regexp-modifiers-i18n.js", // invalid group + "regexp-modifiers.js", // invalid group + "regexp-override-symbol-match-all.js", // missing g flag + "serialize-embedded-error.js", // parseInt() = 0; "string-replace.js", // unstable output + "string-match.js", // deprecated RegExp.$1 etc. + "string-slices-regexp.js", // deprecated RegExp.$1 etc. "omit-default-ctors-array-iterator.js", "mjsunit.js", diff --git a/v8.sh b/v8.sh index c3b1127ac..5a7f724c5 100755 --- a/v8.sh +++ b/v8.sh @@ -1,6 +1,10 @@ #!/bin/sh set -e : ${QJS:=build/qjs} -"$QJS" v8.js $* 2>&1 | tee v8.txt$$ -diff -uw v8.txt v8.txt$$ || exit 1 -rm v8.txt$$ +if [ "x" = "x$1" ] ; then + "$QJS" v8.js $* 2>&1 | tee v8.txt$$ + diff -uw v8.txt v8.txt$$ || exit 1 + rm v8.txt$$ +else + "$QJS" v8.js $* 2>&1 +fi diff --git a/v8.txt b/v8.txt index 178ad6ece..2f98e8d92 100644 --- a/v8.txt +++ b/v8.txt @@ -395,39 +395,6 @@ found: === integer-to-string.js === intl-numberformat-formattoparts.js === intl-pluralrules-select.js -=== invalid-lhs.js -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -threw an exception: invalid assignment left-hand side -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -threw an exception: invalid increment/decrement operand -threw an exception: invalid increment/decrement operand -Object is not an instance of but of -threw an exception: invalid for in/of left hand-side -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -threw an exception: invalid assignment left-hand side -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of -Object is not an instance of but of === invalid-source-element.js === json-errors.js Failure: @@ -508,8 +475,6 @@ Failure: expected found === numops-fuzz-part4.js === obj-construct.js === object-create.js -Failure: expected found -Failure: expected found === object-define-properties.js Failure: expected found <1> === object-freeze-global.js @@ -543,10 +508,6 @@ Failure (printErr should be defined): expected <"function"> found <"undefined"> === readonly-accessor.js === receiver-in-with-calls.js === regexp-UC16.js -=== regexp-cache-replace.js -Failure: expected <"o"> found -Failure: expected <"x"> found -Failure: expected <"o"> found === regexp-call-as-function.js === regexp-capture.js Failure: expected <["",undefined,""]> found <["","undefined",""]> @@ -564,35 +525,10 @@ SyntaxError: too many captures === regexp-loop-capture.js Failure: expected <["abc",undefined,undefined,"c"]> found <["abc","a","b","c"]> Failure: expected <["ab",undefined]> found <["ab","a"]> -=== regexp-modifiers-autogenerated-i18n.js -SyntaxError: invalid group - at regexp-modifiers-autogenerated-i18n.js:12:1 - -=== regexp-modifiers-autogenerated.js -SyntaxError: invalid group - at regexp-modifiers-autogenerated.js:10:1 - -=== regexp-modifiers-dotall.js -SyntaxError: invalid group - at regexp-modifiers-dotall.js:9:1 - -=== regexp-modifiers-i18n.js -SyntaxError: invalid group - at regexp-modifiers-i18n.js:9:1 - -=== regexp-modifiers.js -SyntaxError: invalid group - at regexp-modifiers.js:7:1 - === regexp-multiline.js Failure: expected found Failure: expected found === regexp-override-exec.js -=== regexp-override-symbol-match-all.js -TypeError: regexp must have the 'g' flag - at matchAll (native) - at (regexp-override-symbol-match-all.js:9:23) - === regexp-override-symbol-match.js === regexp-override-symbol-replace.js === regexp-override-symbol-search.js @@ -610,10 +546,6 @@ TypeError: regexp must have the 'g' flag === scope-calls-eval.js === search-string-multiple.js === serialize-after-execute.js -=== serialize-embedded-error.js -SyntaxError: invalid assignment left-hand side - at serialize-embedded-error.js:9:1 - === serialize-ic.js === shifts.js === short-circuit-boolean.js @@ -779,60 +711,6 @@ Did not throw exception Did not throw exception Did not throw exception Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception -Did not throw exception Failure: expected found Failure: expected found found -Failure (Nonglobal-lastMatch): expected <"A"> found -Failure (Nonglobal-nocapture-1): expected <""> found -Failure (Nonglobal-nocapture-2): expected <""> found -Failure (Nonglobal-nocapture-3): expected <""> found -Failure (Nonglobal-nocapture-4): expected <""> found -Failure (Nonglobal-nocapture-5): expected <""> found -Failure (Nonglobal-nocapture-6): expected <""> found -Failure (Nonglobal-nocapture-7): expected <""> found -Failure (Nonglobal-nocapture-8): expected <""> found -Failure (Nonglobal-nocapture-9): expected <""> found -Failure (Nonglobal-input): expected <"A man, a plan, a canal: Panama"> found -Failure (Nonglobal-$_): expected <"A man, a plan, a canal: Panama"> found -Failure (Nonglobal-$`): expected <""> found -Failure (Nonglobal-leftContex): expected <""> found -Failure (Nonglobal-$'): expected <" man, a plan, a canal: Panama"> found -Failure (Nonglobal-rightContex): expected <" man, a plan, a canal: Panama"> found -Failure (Nonglobal-$+): expected <""> found -Failure (Nonglobal-lastParen): expected <""> found -Failure (Nonglobal-ignore-lastIndex-$&): expected <"A"> found -Failure (Nonglobal-ignore-lastIndex-lastMatch): expected <"A"> found -Failure (Nonglobal-ignore-lastIndex-nocapture-1): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-2): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-3): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-4): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-5): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-6): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-7): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-8): expected <""> found -Failure (Nonglobal-ignore-lastIndex-nocapture-9): expected <""> found -Failure (Nonglobal-ignore-lastIndex-input): expected <"A man, a plan, a canal: Panama"> found -Failure (Nonglobal-ignore-lastIndex-$_): expected <"A man, a plan, a canal: Panama"> found -Failure (Nonglobal-ignore-lastIndex-$`): expected <""> found -Failure (Nonglobal-ignore-lastIndex-leftContex): expected <""> found -Failure (Nonglobal-ignore-lastIndex-$'): expected <" man, a plan, a canal: Panama"> found -Failure (Nonglobal-ignore-lastIndex-rightContex): expected <" man, a plan, a canal: Panama"> found -Failure (Nonglobal-ignore-lastIndex-$+): expected <""> found -Failure (Nonglobal-ignore-lastIndex-lastParen): expected <""> found -Failure (Capture-Nonglobal-$&): expected <"abcdefghij"> found -Failure (Capture-Nonglobal-lastMatch): expected <"abcdefghij"> found -Failure (Capture-Nonglobal-capture-1): expected <"a"> found -Failure (Capture-Nonglobal-capture-2): expected <"b"> found -Failure (Capture-Nonglobal-capture-3): expected <"c"> found -Failure (Capture-Nonglobal-capture-4): expected <"d"> found -Failure (Capture-Nonglobal-capture-5): expected <"e"> found -Failure (Capture-Nonglobal-capture-6): expected <"f"> found -Failure (Capture-Nonglobal-capture-7): expected <"g"> found -Failure (Capture-Nonglobal-capture-8): expected <"h"> found -Failure (Capture-Nonglobal-capture-9): expected <"i"> found -Failure (Capture-Nonglobal-input): expected <"abcdefghijxxxxxxxxxx"> found -Failure (Capture-Nonglobal-$_): expected <"abcdefghijxxxxxxxxxx"> found -Failure (Capture-Nonglobal-$`): expected <""> found -Failure (Capture-Nonglobal-leftContex): expected <""> found -Failure (Capture-Nonglobal-$'): expected <"xxxxxxxxxx"> found -Failure (Capture-Nonglobal-rightContex): expected <"xxxxxxxxxx"> found -Failure (Capture-Nonglobal-$+): expected <"j"> found -Failure (Capture-Nonglobal-lastParen): expected <"j"> found -Failure (Global-$&): expected <"glyf"> found -Failure (Global-lastMatch): expected <"glyf"> found -Failure (Global-nocapture-1): expected <""> found -Failure (Global-nocapture-2): expected <""> found -Failure (Global-nocapture-3): expected <""> found -Failure (Global-nocapture-4): expected <""> found -Failure (Global-nocapture-5): expected <""> found -Failure (Global-nocapture-6): expected <""> found -Failure (Global-nocapture-7): expected <""> found -Failure (Global-nocapture-8): expected <""> found -Failure (Global-nocapture-9): expected <""> found -Failure (Global-input): expected <"Argle bargle glop glyf!"> found -Failure (Global-$_): expected <"Argle bargle glop glyf!"> found -Failure (Global-$`): expected <"Argle bargle glop "> found -Failure (Global-leftContex): expected <"Argle bargle glop "> found -Failure (Global-$'): expected <"!"> found -Failure (Global-rightContex): expected <"!"> found -Failure (Global-$+): expected <""> found -Failure (Global-lastParen): expected <""> found -Failure (Global-ignore-lastIndex-$&): expected <"glyf"> found -Failure (Global-ignore-lastIndex-lastMatch): expected <"glyf"> found -Failure (Global-ignore-lastIndex-nocapture-1): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-2): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-3): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-4): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-5): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-6): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-7): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-8): expected <""> found -Failure (Global-ignore-lastIndex-nocapture-9): expected <""> found -Failure (Global-ignore-lastIndex-input): expected <"Argle bargle glop glyf!"> found -Failure (Global-ignore-lastIndex-$_): expected <"Argle bargle glop glyf!"> found -Failure (Global-ignore-lastIndex-$`): expected <"Argle bargle glop "> found -Failure (Global-ignore-lastIndex-leftContex): expected <"Argle bargle glop "> found -Failure (Global-ignore-lastIndex-$'): expected <"!"> found -Failure (Global-ignore-lastIndex-rightContex): expected <"!"> found -Failure (Global-ignore-lastIndex-$+): expected <""> found -Failure (Global-ignore-lastIndex-lastParen): expected <""> found -Failure (Capture-Global-$&): expected <"Panama"> found -Failure (Capture-Global-lastMatch): expected <"Panama"> found -Failure (Capture-Global-capture-1): expected <"anama"> found -Failure (Capture-Global-nocapture-2): expected <""> found - === string-normalize.js === string-oom-concat.js === string-pad.js === string-replace-gc.js === string-replace-one-char.js === string-search.js -=== string-slices-regexp.js -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found -Failure (RegExp.$1): expected <"regexp"> found - === string-split-cache.js === string-trim.js === string-wrapper.js From 7790f318011a97bf513ac9288c3bdf7004329505 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Thu, 28 Mar 2024 11:32:45 +0100 Subject: [PATCH 2/2] Fix strict name conformity cases - reject *future strict reserved words* in `js_parse_function_check_names()`. - add tests for reserved names in tests/test_language.js - allow running tests/test_language.js with v8 - update v8.txt --- quickjs.c | 2 +- tests/test_language.js | 61 ++++++---- v8.js | 11 -- v8.sh | 10 +- v8.txt | 270 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 313 insertions(+), 41 deletions(-) diff --git a/quickjs.c b/quickjs.c index 869806787..cb2940c3a 100644 --- a/quickjs.c +++ b/quickjs.c @@ -34968,7 +34968,7 @@ static int js_obj_to_desc(JSContext *ctx, JSPropertyDescriptor *d, } if ((flags & (JS_PROP_HAS_SET | JS_PROP_HAS_GET)) && (flags & (JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE))) { - JS_ThrowTypeError(ctx, "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute"); + JS_ThrowTypeError(ctx, "cannot have setter/getter and value or writable"); goto fail; } d->flags = flags; diff --git a/tests/test_language.js b/tests/test_language.js index e1c098327..a1cc1bc21 100644 --- a/tests/test_language.js +++ b/tests/test_language.js @@ -422,7 +422,9 @@ function test_argument_scope() var c = "global"; f = function(a = eval("var arguments")) {}; - assert_throws(SyntaxError, f); + // for some reason v8 does not throw an exception here + if (typeof require === 'undefined') + assert_throws(SyntaxError, f); f = function(a = eval("1"), b = arguments[0]) { return b; }; assert(f(12), 12); @@ -537,29 +539,44 @@ function test_function_expr_name() assert_throws(TypeError, f); } -function test_name(name, err) -{ - var s1 = `(function() { var ${name}; ${name} = 1; return ${name}; })()`; - assert(1, eval(s1), `for ${s1}`); - var s1 = `(function(${name}) { ${name} = 1; return ${name}; })()`; - assert(1, eval(s1), `for ${s1}`); - var s1 = `(function ${name}() { return ${name} ? 1 : 0; })()`; - assert(1, eval(s1), `for ${s1}`); - var s2 = `"use strict"; (function() { var ${name}; ${name} = 1; return ${name}; })()`; - if (err) - assert_throws(err, () => eval(s2), `for ${s2}`); - else - assert(1, eval(s2)); - var s2 = `"use strict"; (function(${name}) { ${name} = 1; return ${name}; })()`; - if (err) - assert_throws(err, () => eval(s2), `for ${s2}`); - else - assert(1, eval(s2)); - var s2 = `"use strict"; (function ${name}() { return ${name} ? 1 : 0; })()`; +function test_expr(expr, err) { if (err) - assert_throws(err, () => eval(s2), `for ${s2}`); + assert_throws(err, () => eval(expr), `for ${expr}`); else - assert(1, eval(s2)); + assert(1, eval(expr), `for ${expr}`); +} + +function test_name(name, err) +{ + test_expr(`(function() { return typeof ${name} ? 1 : 1; })()`); + test_expr(`(function() { var ${name}; ${name} = 1; return ${name}; })()`); + test_expr(`(function() { let ${name}; ${name} = 1; return ${name}; })()`, name == 'let' ? SyntaxError : undefined); + test_expr(`(function() { const ${name} = 1; return ${name}; })()`, name == 'let' ? SyntaxError : undefined); + test_expr(`(function(${name}) { ${name} = 1; return ${name}; })()`); + test_expr(`(function({${name}}) { ${name} = 1; return ${name}; })({})`); + test_expr(`(function ${name}() { return ${name} ? 1 : 0; })()`); + test_expr(`"use strict"; (function() { return typeof ${name} ? 1 : 1; })()`, err); + test_expr(`"use strict"; (function() { if (0) ${name} = 1; return 1; })()`, err); + test_expr(`"use strict"; (function() { var x; if (0) x = ${name}; return 1; })()`, err); + test_expr(`"use strict"; (function() { var ${name}; return 1; })()`, err); + test_expr(`"use strict"; (function() { let ${name}; return 1; })()`, err); + test_expr(`"use strict"; (function() { const ${name} = 1; return 1; })()`, err); + test_expr(`"use strict"; (function() { var ${name}; ${name} = 1; return 1; })()`, err); + test_expr(`"use strict"; (function() { var ${name}; ${name} = 1; return ${name}; })()`, err); + test_expr(`"use strict"; (function(${name}) { return 1; })()`, err); + test_expr(`"use strict"; (function({${name}}) { return 1; })({})`, err); + test_expr(`"use strict"; (function ${name}() { return 1; })()`, err); + test_expr(`(function() { "use strict"; return typeof ${name} ? 1 : 1; })()`, err); + test_expr(`(function() { "use strict"; if (0) ${name} = 1; return 1; })()`, err); + test_expr(`(function() { "use strict"; var x; if (0) x = ${name}; return 1; })()`, err); + test_expr(`(function() { "use strict"; var ${name}; return 1; })()`, err); + test_expr(`(function() { "use strict"; let ${name}; return 1; })()`, err); + test_expr(`(function() { "use strict"; const ${name} = 1; return 1; })()`, err); + test_expr(`(function() { "use strict"; var ${name}; ${name} = 1; return 1; })()`, err); + test_expr(`(function() { "use strict"; var ${name}; ${name} = 1; return ${name}; })()`, err); + test_expr(`(function(${name}) { "use strict"; return 1; })()`, err); + test_expr(`(function({${name}}) { "use strict"; return 1; })({})`, SyntaxError); + test_expr(`(function ${name}() { "use strict"; return 1; })()`, err); } function test_reserved_names() diff --git a/v8.js b/v8.js index 34ab65b44..3da78ea87 100644 --- a/v8.js +++ b/v8.js @@ -15,22 +15,11 @@ const exclude = [ "disallow-codegen-from-strings.js", // --disallow-code-generation-from-strings "cyclic-array-to-string.js", // unstable output due to stack overflow "error-tostring.js", // unstable output due to stack overflow - "invalid-lhs.js", // v8 expects ReferenceError but ECMA says SyntaxError "regexp.js", // invalid, legitimate early SyntaxError "regexp-capture-3.js", // slow - "regexp-cache-replace.js", // deprecated RegExp.$1 etc. "regexp-indexof.js", // deprecated RegExp.lastMatch etc. "regexp-static.js", // deprecated RegExp static properties. - "regexp-modifiers-autogenerated-i18n.js", // invalid group - "regexp-modifiers-autogenerated.js", // invalid group - "regexp-modifiers-dotall.js", // invalid group - "regexp-modifiers-i18n.js", // invalid group - "regexp-modifiers.js", // invalid group - "regexp-override-symbol-match-all.js", // missing g flag - "serialize-embedded-error.js", // parseInt() = 0; "string-replace.js", // unstable output - "string-match.js", // deprecated RegExp.$1 etc. - "string-slices-regexp.js", // deprecated RegExp.$1 etc. "omit-default-ctors-array-iterator.js", "mjsunit.js", diff --git a/v8.sh b/v8.sh index 5a7f724c5..c3b1127ac 100755 --- a/v8.sh +++ b/v8.sh @@ -1,10 +1,6 @@ #!/bin/sh set -e : ${QJS:=build/qjs} -if [ "x" = "x$1" ] ; then - "$QJS" v8.js $* 2>&1 | tee v8.txt$$ - diff -uw v8.txt v8.txt$$ || exit 1 - rm v8.txt$$ -else - "$QJS" v8.js $* 2>&1 -fi +"$QJS" v8.js $* 2>&1 | tee v8.txt$$ +diff -uw v8.txt v8.txt$$ || exit 1 +rm v8.txt$$ diff --git a/v8.txt b/v8.txt index 2f98e8d92..08026bf67 100644 --- a/v8.txt +++ b/v8.txt @@ -395,6 +395,39 @@ found: === integer-to-string.js === intl-numberformat-formattoparts.js === intl-pluralrules-select.js +=== invalid-lhs.js +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +threw an exception: invalid assignment left-hand side +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +threw an exception: invalid increment/decrement operand +threw an exception: invalid increment/decrement operand +Object is not an instance of but of +threw an exception: invalid for in/of left hand-side +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +threw an exception: invalid assignment left-hand side +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of +Object is not an instance of but of === invalid-source-element.js === json-errors.js Failure: @@ -475,6 +508,8 @@ Failure: expected found === numops-fuzz-part4.js === obj-construct.js === object-create.js +Failure: expected found +Failure: expected found === object-define-properties.js Failure: expected found <1> === object-freeze-global.js @@ -508,6 +543,10 @@ Failure (printErr should be defined): expected <"function"> found <"undefined"> === readonly-accessor.js === receiver-in-with-calls.js === regexp-UC16.js +=== regexp-cache-replace.js +Failure: expected <"o"> found +Failure: expected <"x"> found +Failure: expected <"o"> found === regexp-call-as-function.js === regexp-capture.js Failure: expected <["",undefined,""]> found <["","undefined",""]> @@ -525,10 +564,35 @@ SyntaxError: too many captures === regexp-loop-capture.js Failure: expected <["abc",undefined,undefined,"c"]> found <["abc","a","b","c"]> Failure: expected <["ab",undefined]> found <["ab","a"]> +=== regexp-modifiers-autogenerated-i18n.js +SyntaxError: invalid group + at regexp-modifiers-autogenerated-i18n.js:12:1 + +=== regexp-modifiers-autogenerated.js +SyntaxError: invalid group + at regexp-modifiers-autogenerated.js:10:1 + +=== regexp-modifiers-dotall.js +SyntaxError: invalid group + at regexp-modifiers-dotall.js:9:1 + +=== regexp-modifiers-i18n.js +SyntaxError: invalid group + at regexp-modifiers-i18n.js:9:1 + +=== regexp-modifiers.js +SyntaxError: invalid group + at regexp-modifiers.js:7:1 + === regexp-multiline.js Failure: expected found Failure: expected found === regexp-override-exec.js +=== regexp-override-symbol-match-all.js +TypeError: regexp must have the 'g' flag + at matchAll (native) + at (regexp-override-symbol-match-all.js:9:23) + === regexp-override-symbol-match.js === regexp-override-symbol-replace.js === regexp-override-symbol-search.js @@ -546,6 +610,10 @@ Failure: expected found === scope-calls-eval.js === search-string-multiple.js === serialize-after-execute.js +=== serialize-embedded-error.js +SyntaxError: invalid assignment left-hand side + at serialize-embedded-error.js:9:1 + === serialize-ic.js === shifts.js === short-circuit-boolean.js @@ -745,12 +813,214 @@ TypeError: cannot read property 'value' of undefined === string-indexof-2.js === string-lastindexof.js === string-localecompare.js +=== string-match.js +Failure (Nonglobal-$&): expected <"A"> found +Failure (Nonglobal-lastMatch): expected <"A"> found +Failure (Nonglobal-nocapture-1): expected <""> found +Failure (Nonglobal-nocapture-2): expected <""> found +Failure (Nonglobal-nocapture-3): expected <""> found +Failure (Nonglobal-nocapture-4): expected <""> found +Failure (Nonglobal-nocapture-5): expected <""> found +Failure (Nonglobal-nocapture-6): expected <""> found +Failure (Nonglobal-nocapture-7): expected <""> found +Failure (Nonglobal-nocapture-8): expected <""> found +Failure (Nonglobal-nocapture-9): expected <""> found +Failure (Nonglobal-input): expected <"A man, a plan, a canal: Panama"> found +Failure (Nonglobal-$_): expected <"A man, a plan, a canal: Panama"> found +Failure (Nonglobal-$`): expected <""> found +Failure (Nonglobal-leftContex): expected <""> found +Failure (Nonglobal-$'): expected <" man, a plan, a canal: Panama"> found +Failure (Nonglobal-rightContex): expected <" man, a plan, a canal: Panama"> found +Failure (Nonglobal-$+): expected <""> found +Failure (Nonglobal-lastParen): expected <""> found +Failure (Nonglobal-ignore-lastIndex-$&): expected <"A"> found +Failure (Nonglobal-ignore-lastIndex-lastMatch): expected <"A"> found +Failure (Nonglobal-ignore-lastIndex-nocapture-1): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-2): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-3): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-4): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-5): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-6): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-7): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-8): expected <""> found +Failure (Nonglobal-ignore-lastIndex-nocapture-9): expected <""> found +Failure (Nonglobal-ignore-lastIndex-input): expected <"A man, a plan, a canal: Panama"> found +Failure (Nonglobal-ignore-lastIndex-$_): expected <"A man, a plan, a canal: Panama"> found +Failure (Nonglobal-ignore-lastIndex-$`): expected <""> found +Failure (Nonglobal-ignore-lastIndex-leftContex): expected <""> found +Failure (Nonglobal-ignore-lastIndex-$'): expected <" man, a plan, a canal: Panama"> found +Failure (Nonglobal-ignore-lastIndex-rightContex): expected <" man, a plan, a canal: Panama"> found +Failure (Nonglobal-ignore-lastIndex-$+): expected <""> found +Failure (Nonglobal-ignore-lastIndex-lastParen): expected <""> found +Failure (Capture-Nonglobal-$&): expected <"abcdefghij"> found +Failure (Capture-Nonglobal-lastMatch): expected <"abcdefghij"> found +Failure (Capture-Nonglobal-capture-1): expected <"a"> found +Failure (Capture-Nonglobal-capture-2): expected <"b"> found +Failure (Capture-Nonglobal-capture-3): expected <"c"> found +Failure (Capture-Nonglobal-capture-4): expected <"d"> found +Failure (Capture-Nonglobal-capture-5): expected <"e"> found +Failure (Capture-Nonglobal-capture-6): expected <"f"> found +Failure (Capture-Nonglobal-capture-7): expected <"g"> found +Failure (Capture-Nonglobal-capture-8): expected <"h"> found +Failure (Capture-Nonglobal-capture-9): expected <"i"> found +Failure (Capture-Nonglobal-input): expected <"abcdefghijxxxxxxxxxx"> found +Failure (Capture-Nonglobal-$_): expected <"abcdefghijxxxxxxxxxx"> found +Failure (Capture-Nonglobal-$`): expected <""> found +Failure (Capture-Nonglobal-leftContex): expected <""> found +Failure (Capture-Nonglobal-$'): expected <"xxxxxxxxxx"> found +Failure (Capture-Nonglobal-rightContex): expected <"xxxxxxxxxx"> found +Failure (Capture-Nonglobal-$+): expected <"j"> found +Failure (Capture-Nonglobal-lastParen): expected <"j"> found +Failure (Global-$&): expected <"glyf"> found +Failure (Global-lastMatch): expected <"glyf"> found +Failure (Global-nocapture-1): expected <""> found +Failure (Global-nocapture-2): expected <""> found +Failure (Global-nocapture-3): expected <""> found +Failure (Global-nocapture-4): expected <""> found +Failure (Global-nocapture-5): expected <""> found +Failure (Global-nocapture-6): expected <""> found +Failure (Global-nocapture-7): expected <""> found +Failure (Global-nocapture-8): expected <""> found +Failure (Global-nocapture-9): expected <""> found +Failure (Global-input): expected <"Argle bargle glop glyf!"> found +Failure (Global-$_): expected <"Argle bargle glop glyf!"> found +Failure (Global-$`): expected <"Argle bargle glop "> found +Failure (Global-leftContex): expected <"Argle bargle glop "> found +Failure (Global-$'): expected <"!"> found +Failure (Global-rightContex): expected <"!"> found +Failure (Global-$+): expected <""> found +Failure (Global-lastParen): expected <""> found +Failure (Global-ignore-lastIndex-$&): expected <"glyf"> found +Failure (Global-ignore-lastIndex-lastMatch): expected <"glyf"> found +Failure (Global-ignore-lastIndex-nocapture-1): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-2): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-3): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-4): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-5): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-6): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-7): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-8): expected <""> found +Failure (Global-ignore-lastIndex-nocapture-9): expected <""> found +Failure (Global-ignore-lastIndex-input): expected <"Argle bargle glop glyf!"> found +Failure (Global-ignore-lastIndex-$_): expected <"Argle bargle glop glyf!"> found +Failure (Global-ignore-lastIndex-$`): expected <"Argle bargle glop "> found +Failure (Global-ignore-lastIndex-leftContex): expected <"Argle bargle glop "> found +Failure (Global-ignore-lastIndex-$'): expected <"!"> found +Failure (Global-ignore-lastIndex-rightContex): expected <"!"> found +Failure (Global-ignore-lastIndex-$+): expected <""> found +Failure (Global-ignore-lastIndex-lastParen): expected <""> found +Failure (Capture-Global-$&): expected <"Panama"> found +Failure (Capture-Global-lastMatch): expected <"Panama"> found +Failure (Capture-Global-capture-1): expected <"anama"> found +Failure (Capture-Global-nocapture-2): expected <""> found + === string-normalize.js === string-oom-concat.js === string-pad.js === string-replace-gc.js === string-replace-one-char.js === string-search.js +=== string-slices-regexp.js +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found +Failure (RegExp.$1): expected <"regexp"> found + === string-split-cache.js === string-trim.js === string-wrapper.js