swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
30.91k stars 1.2k forks source link

swc_ecma_parser: Unexpected escape sequence in reserved word (2) #9227

Open sebastiano-barrera opened 1 month ago

sebastiano-barrera commented 1 month ago

Describe the bug

Have swc_ecma_parser parse this test262 case: test/language/import/import-assertions/json-extensibility-array.js (others also exhibit this behavior).

(This is a re-post of #9214, this time with a proper reproduction link that works on the latest parser version, 0.147.0)

Input code

var obj = ({ bre\u0061k: 42 });

Config

(I'm only using swc_ecma_parser in my toy/learning JS impl; I'm not using the full swc and I don't have an .swcrc)

fwiw:
Syntax::Es(Default::default())
EsVersion::Es2015

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.6.7&code=H4sIAAAAAAAAAytLLFLIT8pSsFXQqFZIKkqNKTUwMDPMtlIwMVKo1bTmAgDLr8KQIAAAAA%3D%3D&config=H4sIAAAAAAAAA1VPSQ7CMAy89xWRzxwACQ78gUdYwa1SZVMcJKKqfyfNUujNs3nsZRACZpbwEEseM%2FAYmMKOM8PJRvxkBkgaZBmUj3Dq6sybNKJmKtRaFYgYJoolxdfz5dYSoJ1j6onGGWXVmP47pTM%2BEPPRuFnRTpqOjUNrBeNe7yK2X2LyVC%2B4w8%2FUy%2FbFoPjZk3Xt%2BgVne8%2FLGAEAAA%3D%3D

SWC Info output

No response

Expected behavior

The above code is parsed as an object literal with property "var" (which is legal JS). This works in node.

Actual behavior

The following error is reported:

error: Unexpected escape sequence in reserved word: var
  --> <anon>:37:14
   |
37 | var obj = ({ v\u0061r: 42 });
   |              ^^^^^^^^

Version

0.147.0

Additional context

The relevant code that calls the parser is the following (just an extract; the original with full context is here):

use swc_ecma_ast::EsVersion;
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};

// ...
// content: String
let source_file = source_map.new_source_file(swc_common::FileName::Anon, content);
let input = StringInput::from(source_file.as_ref());

// ...

let lexer = Lexer::new(
    Syntax::Es(Default::default()),
    EsVersion::Es2015,
    input,
    None,
);
let mut parser = Parser::new_from(lexer);

// ...

let script_ast = parser
    .parse_script()
    .map_err(|e| {
        e.into_diagnostic(&err_handler).emit();
        error!("parse error")
    });
kdy1 commented 1 month ago

GFI guide

37 | var obj = ({ v\u0061r: 42 });

This is about an object lieral, and the relevant code lives at

https://github.com/swc-project/swc/blob/1ec68cb5b198e0acac321266f6b606e6407d41eb/crates/swc_ecma_parser/src/parser/object.rs#L183-L212

It seems like parse_prop_name has a bug.

parse_prop_name is declared as

https://github.com/swc-project/swc/blob/1ec68cb5b198e0acac321266f6b606e6407d41eb/crates/swc_ecma_parser/src/parser/object.rs#L43-L122

But there's no relevant error reporting logic so my guess is that the error is from lexer. The relevant error reporting logic is at https://github.com/swc-project/swc/blob/1ec68cb5b198e0acac321266f6b606e6407d41eb/crates/swc_ecma_parser/src/lexer/mod.rs#L777-L780

We need to patch this logic to allow escapes in reserved word in property names.

sebastiano-barrera commented 1 month ago

I'm going to take a stab at it

CPunisher commented 2 days ago

Fixing this bug is not as simple as adding a new context flag. Since swc parser reads next token automatically when last token is taken, we can't figure out where to add the new context flag.

Specifically, I think the token reading happens at: https://github.com/swc-project/swc/blob/c43dbad028072396390029af44e31bc3292a342a/crates/swc_ecma_parser/src/parser/object.rs#L27 We can't assume the parser is going to parse https://tc39.es/ecma262/#prod-LiteralPropertyName, therefore it is not proper to add the context flag there.

sebastiano-barrera commented 2 days ago

Yes, that's what I figured. I also tried "forwarding" richer info downstream of the lexer (PR #9236), so that the identifier/keyword ambiguity can be resolved in a later phase, but it seems to be a dead end.

(In an unrelated note: I've kind of given up on this bug. I've been focusing on other stuff since, and this bug isn't really bothering me much. I'm not sure how much more I can contribute here; looks like the necessary effort is out of reach for me now.)