From bdc241d41d8b1b954cf23bb8d80b8492f7132a9a Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Wed, 25 Dec 2024 11:22:54 +0000 Subject: [PATCH] fix(codegen): disallow template literals in object property key (#8108) --- crates/oxc_codegen/src/gen.rs | 5 ++++- crates/oxc_codegen/src/lib.rs | 22 +++++++------------- crates/oxc_codegen/tests/integration/unit.rs | 2 ++ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 937524494..f5cee102b 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1337,7 +1337,7 @@ impl Gen for StringLiteral<'_> { fn gen(&self, p: &mut Codegen, _ctx: Context) { p.add_source_mapping(self.span); let s = self.value.as_str(); - p.print_quoted_utf16(s); + p.print_quoted_utf16(s, /* allow_backtick */ true); } } @@ -1647,6 +1647,9 @@ impl Gen for PropertyKey<'_> { match self { Self::StaticIdentifier(ident) => ident.print(p, ctx), Self::PrivateIdentifier(ident) => ident.print(p, ctx), + Self::StringLiteral(s) => { + p.print_quoted_utf16(s.value.as_str(), /* allow_backtick */ false); + } match_expression!(Self) => { self.to_expression().print_expr(p, Precedence::Comma, Context::empty()); } diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index daf8d22ca..5fb02ce43 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -587,7 +587,7 @@ impl<'a> Codegen<'a> { } } - fn print_quoted_utf16(&mut self, s: &str) { + fn print_quoted_utf16(&mut self, s: &str, allow_backtick: bool) { let quote = if self.options.minify { let mut single_cost: u32 = 0; let mut double_cost: u32 = 0; @@ -595,18 +595,10 @@ impl<'a> Codegen<'a> { let mut bytes = s.as_bytes().iter().peekable(); while let Some(b) = bytes.next() { match b { - b'\n' if self.options.minify => { - backtick_cost = backtick_cost.saturating_sub(1); - } - b'\'' => { - single_cost += 1; - } - b'"' => { - double_cost += 1; - } - b'`' => { - backtick_cost += 1; - } + b'\n' if self.options.minify => backtick_cost = backtick_cost.saturating_sub(1), + b'\'' => single_cost += 1, + b'"' => double_cost += 1, + b'`' => backtick_cost += 1, b'$' => { if bytes.peek() == Some(&&b'{') { backtick_cost += 1; @@ -618,10 +610,10 @@ impl<'a> Codegen<'a> { let mut quote = b'"'; if double_cost > single_cost { quote = b'\''; - if single_cost > backtick_cost { + if single_cost > backtick_cost && allow_backtick { quote = b'`'; } - } else if double_cost > backtick_cost { + } else if double_cost > backtick_cost && allow_backtick { quote = b'`'; } quote diff --git a/crates/oxc_codegen/tests/integration/unit.rs b/crates/oxc_codegen/tests/integration/unit.rs index 1a8525f82..36d66059d 100644 --- a/crates/oxc_codegen/tests/integration/unit.rs +++ b/crates/oxc_codegen/tests/integration/unit.rs @@ -43,6 +43,8 @@ fn expr() { r#";'eval("\'\\vstr\\ving\\v\'") === "\\vstr\\ving\\v"'"#, r#";`eval("'\\vstr\\ving\\v'") === "\\vstr\\ving\\v"`;"#, ); + + test_minify_same(r#"({"http://a\r\" \n<'b:b@c\r\nd/e?f":{}});"#); } #[test]