From 23f9635d2cb523d63e5d1611dcf55922bcc54a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Mon, 11 Mar 2024 15:52:57 +0900 Subject: [PATCH] fix(es/minifier): Do not evaluate `slice` calls with negative index (#8726) **Related issue:** - Closes #8715. --- .../src/compress/pure/evaluate.rs | 12 +++++ .../tests/fixture/issues/8715/config.json | 47 +++++++++++++++++++ .../tests/fixture/issues/8715/input.js | 2 + .../tests/fixture/issues/8715/output.js | 9 ++++ 4 files changed, 70 insertions(+) create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/8715/config.json create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/8715/input.js create mode 100644 crates/swc_ecma_minifier/tests/fixture/issues/8715/output.js diff --git a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs index cd2ac1aea26d..1c29a585a298 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs @@ -76,6 +76,10 @@ impl Pure<'_> { if let Value::Known(start) = call.args[0].expr.as_pure_number(&self.expr_ctx) { + if start.is_sign_negative() { + return; + } + let start = start.floor() as usize; self.changed = true; @@ -98,9 +102,17 @@ impl Pure<'_> { let start = call.args[0].expr.as_pure_number(&self.expr_ctx); let end = call.args[1].expr.as_pure_number(&self.expr_ctx); if let Value::Known(start) = start { + if start.is_sign_negative() { + return; + } + let start = start.floor() as usize; if let Value::Known(end) = end { + if end.is_sign_negative() { + return; + } + let end = end.floor() as usize; let end = end.min(arr.elems.len()); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8715/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/8715/config.json new file mode 100644 index 000000000000..7e144b291fa7 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8715/config.json @@ -0,0 +1,47 @@ +{ + "defaults": true, + "arguments": false, + "arrows": true, + "booleans": true, + "booleans_as_integers": false, + "collapse_vars": true, + "comparisons": true, + "computed_props": true, + "conditionals": true, + "dead_code": true, + "directives": true, + "drop_console": false, + "drop_debugger": true, + "evaluate": true, + "expression": false, + "hoist_funs": false, + "hoist_props": true, + "hoist_vars": false, + "if_return": true, + "join_vars": true, + "keep_classnames": false, + "keep_fargs": true, + "keep_fnames": false, + "keep_infinity": false, + "loops": true, + "negate_iife": true, + "properties": true, + "reduce_funcs": false, + "reduce_vars": false, + "side_effects": true, + "switches": true, + "typeofs": true, + "unsafe": false, + "unsafe_arrows": false, + "unsafe_comps": false, + "unsafe_Function": false, + "unsafe_math": false, + "unsafe_symbols": false, + "unsafe_methods": false, + "unsafe_proto": false, + "unsafe_regexp": false, + "unsafe_undefined": false, + "unused": true, + "const_to_let": true, + "pristine_globals": true +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8715/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/8715/input.js new file mode 100644 index 000000000000..60fd274a2540 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8715/input.js @@ -0,0 +1,2 @@ +console.log([1, 2, 3].slice(-1)) +console.log([1, 2, 3].slice(-1, 0)) diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8715/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/8715/output.js new file mode 100644 index 000000000000..823840bb3e2c --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8715/output.js @@ -0,0 +1,9 @@ +console.log([ + 1, + 2, + 3 +].slice(-1)), console.log([ + 1, + 2, + 3 +].slice(-1, 0));