mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(minifier): preserve catch binding with direct eval (#22221)
Given:
```
try {
throw "error"
} catch (e) {
eval('console.log(e)')
}
```
The expected runtime behaviour is
```
"error"
```
instead, runtime behaviour is:
```
Uncaught ReferenceError: e is not defined
at eval (eval at <anonymous> (REPL5:4:3), <anonymous>:1:13)
```
This is because we remove the catch parameter, as we see no references to it, despite it being referenced in the `eval` call.
This PR adds a check to see if we are in a direct eval scope, and bails removing the catch parameter if this is the case.
This commit is contained in:
1 parent
0e13d17c8b
commit
73b4f40d23
2 files changed
+4
No files matched your search
@@ -1674,6 +1674,8 @@ impl<'a> PeepholeOptimizations {
|
||||
&& let Some(param) = &catch.param
|
||||
&& let BindingPattern::BindingIdentifier(ident) = ¶m.pattern
|
||||
&& (catch.body.body.is_empty() || ctx.scoping().symbol_is_unused(ident.symbol_id()))
|
||||
// Direct eval can reference the catch parameter even when static analysis sees no use.
|
||||
&& !ctx.scoping().scope_flags(catch.scope_id()).contains_direct_eval()
|
||||
// Don't remove catch parameter when the body has a `var` with the same name.
|
||||
// In `catch (e) { var e = x }`, `var e` hoists to function scope but the assignment
|
||||
// targets the catch parameter. Removing the catch param changes semantics.
|
||||
|
||||
@@ -753,6 +753,8 @@ fn optional_catch_binding() {
|
||||
test("try { foo } catch(e) {}", "try { foo } catch {}");
|
||||
test("try { foo } catch(e) {foo}", "try { foo } catch {foo}");
|
||||
test_same("try { foo } catch(e) { bar(e) }");
|
||||
test_same("try { throw 'caught'; } catch (e) { eval('console.log(e)'); }");
|
||||
test_same("try { throw 'caught'; } catch (e) { function f() { eval('console.log(e)') } f() }");
|
||||
test_same("try { foo } catch([e]) {}");
|
||||
test_same("try { foo } catch({e}) {}");
|
||||
test_same("try { foo } catch(e) { var e = baz; bar(e) }");
|
||||
|
||||
Reference in new issue
Block a user