From dfc135414a54edee72dcaa713b7d3883ca498166 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 16 Oct 2026 15:13:16 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E6=9E=90=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E7=95=B8=E5=BD=A2=E8=BE=93=E5=85=A5=E6=B7=B1=E5=BA=A6=E4=B8=8B?= =?UTF-8?q?=E6=BA=A2=E4=B8=8E=E4=B8=A5=E6=A0=BC=E5=87=BD=E6=95=B0=E4=BD=93?= =?UTF-8?q?=E5=8C=BA=E9=97=B4=E6=94=B6=E9=9B=86=E7=BC=BA=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 42 ++++++------- Cargo.toml | 2 +- crates/oxide_builtins/src/date.rs | 9 ++- crates/oxide_parser/src/call_lhs_rewrite.rs | 70 +++++++++++++++++++-- 4 files changed, 92 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61e9fba3..6cab91a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.19.33" +version = "0.19.34" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.19.33" +version = "0.19.34" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.19.33" +version = "0.19.34" dependencies = [ "ansi_term", "bumpalo", @@ -1228,7 +1228,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.19.33" +version = "0.19.34" dependencies = [ "lru", "oxide_bytecode", @@ -1237,7 +1237,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1258,7 +1258,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1272,7 +1272,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.19.33" +version = "0.19.34" dependencies = [ "num-bigint", "oxc_allocator", @@ -1288,7 +1288,7 @@ dependencies = [ [[package]] name = "oxide_engine" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1300,7 +1300,7 @@ dependencies = [ [[package]] name = "oxide_fold" -version = "0.19.33" +version = "0.19.34" dependencies = [ "num-bigint", "oxide_bytecode", @@ -1312,7 +1312,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1321,7 +1321,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.19.33" +version = "0.19.34" dependencies = [ "bumpalo", "dashmap", @@ -1335,7 +1335,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1347,7 +1347,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.19.33" +version = "0.19.34" dependencies = [ "tracing", "tracing-appender", @@ -1356,11 +1356,11 @@ dependencies = [ [[package]] name = "oxide_net" -version = "0.19.33" +version = "0.19.34" [[package]] name = "oxide_parser" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1391,7 +1391,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.19.33" +version = "0.19.34" dependencies = [ "num-bigint", "num-traits", @@ -1404,7 +1404,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.19.33" +version = "0.19.34" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1424,7 +1424,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.19.33" +version = "0.19.34" dependencies = [ "bumpalo", "dashmap", @@ -1437,7 +1437,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.19.33" +version = "0.19.34" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index f20be145..25b4c291 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ members = [ ] [workspace.package] -version = "0.19.33" +version = "0.19.34" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_builtins/src/date.rs b/crates/oxide_builtins/src/date.rs index 057a33b2..60c2c612 100644 --- a/crates/oxide_builtins/src/date.rs +++ b/crates/oxide_builtins/src/date.rs @@ -408,8 +408,7 @@ fn parse_iso_strict(s: &str) -> Option { // 年:可选符号;带符号恒为 6 位扩展年,无符号为 4 位年或 6 位扩展年 // (第 5 位起为数字时读满 6 位)。 - let y: i64; - if pos < b.len() && (b[pos] == b'+' || b[pos] == b'-') { + let y: i64 = if pos < b.len() && (b[pos] == b'+' || b[pos] == b'-') { let neg = b[pos] == b'-'; pos += 1; if b.len() - pos < 6 || !b[pos..pos + 6].iter().all(|c| c.is_ascii_digit()) { @@ -421,7 +420,7 @@ fn parse_iso_strict(s: &str) -> Option { return None; } pos += 6; - y = if neg { -yv } else { yv }; + if neg { -yv } else { yv } } else { if b.len() - pos < 4 || !b[pos..pos + 4].iter().all(|c| c.is_ascii_digit()) { return None; @@ -432,8 +431,8 @@ fn parse_iso_strict(s: &str) -> Option { yv = yv * 100 + (b[pos] - b'0') as i64 * 10 + (b[pos + 1] - b'0') as i64; pos += 2; } - y = yv; - } + yv + }; // 纯年形式(YYYY):当年 1 月 1 日 UTC 零点。 if pos == b.len() { diff --git a/crates/oxide_parser/src/call_lhs_rewrite.rs b/crates/oxide_parser/src/call_lhs_rewrite.rs index ec067ea7..eb3fb55c 100644 --- a/crates/oxide_parser/src/call_lhs_rewrite.rs +++ b/crates/oxide_parser/src/call_lhs_rewrite.rs @@ -499,7 +499,9 @@ fn find_stmt_end(toks: &[Tok], src: &str, start: usize) -> Option<(usize, bool)> if toks[j].kind == Kind::Punct { match tok_val(src, &toks[j]) { "(" | "[" | "{" => depth += 1, - ")" | "]" => depth -= 1, + // 右括号在深度为零时出现(畸形输入),饱和减保持深度为零, + // 扫描继续到末尾后安全退出,不回绕也不 panic。 + ")" | "]" => depth = depth.saturating_sub(1), "}" if depth == 0 => return Some((j, false)), "}" => depth -= 1, ";" if depth == 0 => return Some((j, true)), @@ -553,7 +555,7 @@ fn is_directive_strict(toks: &[Tok], src: &str, stmt_tok: usize) -> bool { } /// 收集严格函数体区间(函数体首语句为 "use strict" 指令):`function` 声明/ -/// 表达式与箭头函数块体。返回字节区间列表,区间内不改写。 +/// 表达式、箭头函数块体与对象/类方法体。返回字节区间列表,区间内不改写。 fn collect_strict_regions(toks: &[Tok], src: &str) -> Vec<(usize, usize)> { let mut regions = Vec::new(); let mut i = 0usize; @@ -571,6 +573,18 @@ fn collect_strict_regions(toks: &[Tok], src: &str) -> Vec<(usize, usize)> { } } + // 对象/类方法体:名字后(可选 `*`)紧跟参数括号与 `{`。 + // `get`/`set`/`async`/`static` 前缀落在名字之前,锚定名字即覆盖。 + if t.kind == Kind::Ident { + if let Some(open) = method_body_open(toks, src, i) { + if let Some(close) = match_brace(toks, src, open) { + if is_directive_strict(toks, src, open + 1) { + regions.push((toks[open].start, toks[close].end)); + } + } + } + } + // 箭头函数块体:=> 后直接跟 { if t.kind == Kind::Punct && v == "=>" { if let Some(next) = toks.get(i + 1) { @@ -590,12 +604,35 @@ fn collect_strict_regions(toks: &[Tok], src: &str) -> Vec<(usize, usize)> { } /// 从 `function` token 起定位函数体的 `{` 下标:跳过可选函数名与 `*`, -/// 平衡参数括号后须紧跟 `{`。 +/// 平衡参数括号后须紧跟 `{`。星号可紧邻关键字(`function* name`)也可紧邻 +/// 参数括号(`function name*`),两种顺序都跳过。 fn function_body_open(toks: &[Tok], src: &str, i: usize) -> Option { let mut j = i + 1; - if j < toks.len() && toks[j].kind == Kind::Ident { + if j < toks.len() && toks[j].kind == Kind::Punct && tok_val(src, &toks[j]) == "*" { j += 1; } + if j < toks.len() && toks[j].kind == Kind::Ident { + j += 1; + if j < toks.len() && toks[j].kind == Kind::Punct && tok_val(src, &toks[j]) == "*" { + j += 1; + } + } + if j >= toks.len() || toks[j].kind != Kind::Punct || tok_val(src, &toks[j]) != "(" { + return None; + } + let close = match_paren(toks, src, j)?; + let k = close + 1; + if k < toks.len() && toks[k].kind == Kind::Punct && tok_val(src, &toks[k]) == "{" { + return Some(k); + } + None +} + +/// 从方法名 token 起定位方法体的 `{` 下标:跳过可选 `*`(生成器方法), +/// 平衡参数括号后须紧跟 `{`。调用表达式后不合法地跟块,此形态只会命中 +/// 对象/类方法定义(或非法源,安全方向同函数臂)。 +fn method_body_open(toks: &[Tok], src: &str, i: usize) -> Option { + let mut j = i + 1; if j < toks.len() && toks[j].kind == Kind::Punct && tok_val(src, &toks[j]) == "*" { j += 1; } @@ -898,6 +935,13 @@ mod tests { let src = "f()`` = 1;"; assert_eq!(rw(src), src); } + + // 畸形输入(语句未闭合多一个右括号)原样透传,不 panic 也不改写 + #[test] + fn unbalanced_stmt_end_not_rewritten() { + let src = "f() = 1)"; + assert_eq!(rw(src), src); + } } #[cfg(test)] @@ -924,4 +968,22 @@ mod probe { let src = "function() { \"use strict\"; f() = g(); }"; assert_eq!(rw(src), src); } + // strict 具名生成器体(星号在函数名之前)不改写 + #[test] + fn strict_named_generator_body_not_rewritten() { + let src = "function* g() { \"use strict\"; f() = g(); }"; + assert_eq!(rw(src), src); + } + // strict 对象方法体不改写 + #[test] + fn strict_object_method_body_not_rewritten() { + let src = "o = { m() { \"use strict\"; f() = g(); } };"; + assert_eq!(rw(src), src); + } + // strict 类方法体不改写 + #[test] + fn strict_class_method_body_not_rewritten() { + let src = "class C { m() { \"use strict\"; f() = g(); } }"; + assert_eq!(rw(src), src); + } }