Skip to content

Reject array literals without ',' between elements - #1905

Open
gengjiawen wants to merge 1 commit into
quickjs-ng:masterfrom
gengjiawen:fix-array-literal-comma-check
Open

gengjiawen wants to merge 1 commit into
quickjs-ng:masterfrom
gengjiawen:fix-array-literal-comma-check

Conversation

@gengjiawen

Copy link
Copy Markdown
Contributor

js_parse_array_literal() parses an array in up to three loops: the first one handles at most 32 elements without holes, the second one continues with explicit indices after a hole or after the 32nd element, and the third one takes over at the first spread element. The first and third loops require a , between elements. The second one consumes a , if there is one but does not require it, so on master:

[, 1 2]                      // [ <empty>, 1, 2 ]
[1, , 2 3]                   // length 4
[, 1 ...[2]]                 // [ <empty>, 1, 2 ]
[0, 0, /* 30 more, */ 1 2]   // any ',' missing after the 32nd element

This adds the check that the first loop already has. They are now rejected with the same messages as in V8 (SyntaxError: Unexpected number, Unexpected token '...').

bellard/quickjs master (e585640) has the same code.

Testing

  • New test_array_literal() in tests/test_language.js: holes, trailing commas and more than 32 elements still work, and 5 of the 6 assert_throws lines compile on master ([1 2] is the one that was already rejected).
  • make test (0/123 errors), api-test, lre-test, make jscheck, and make codegen leaves the tree clean. Built with gcc 15 (Release) and clang 21 (Debug, QJS_BUILD_WERROR=ON).
  • make test262: 64/82550 errors, same as master, also with ASan+UBSan. (With ASan+UBSan, make test has one failure, test_std.js test_poll_handler_order. It fails the same way on master on this machine and passes when run alone; it depends on a 100 ms timer.)
  • All 49,215 files of test262 and tests/ that compile produce the same bytecode as on master (compared the JS_WriteObject() output), and so do 12 large real-world files (24 MB: typescript.js, antd, monaco-editor, three.js, ...).
  • 600,000 random array literals (holes, spreads, nesting, up to 40 elements, separators randomly missing or doubled) compiled by master, this branch and V8 (node 26.13). Master accepts 4,304 that V8 rejects; this branch agrees with V8 on all 600,000.

Prepared with the assistance of Claude Fable 5.2.

js_parse_array_literal() parses what follows a hole or the 32nd
element in a second loop. Unlike the first loop, it accepted a ','
after each element but did not require one:

    [, 1 2]         // [ <empty>, 1, 2 ]
    [1, , 2 3]      // length 4
    [, 1 ...[2]]    // [ <empty>, 1, 2 ]

and likewise for any ',' missing after the 32nd element. These are now
a SyntaxError.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant