Skip to content

Commit

Permalink
safely evaluate .length of arrays and strings
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiosantoscode committed Apr 17, 2023
1 parent 94ae068 commit 31753d0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
29 changes: 28 additions & 1 deletion lib/compress/evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,16 +352,43 @@ const regexp_flags = new Set([
def_eval(AST_PropAccess, function (compressor, depth) {
let obj = this.expression._eval(compressor, depth + 1);
if (obj === nullish || (this.optional && obj == null)) return nullish;

// `.length` of strings and arrays is always safe
if (this.property === "length") {
if (typeof obj === "string") {
return obj.length;
}

const is_spreadless_array = obj =>
obj instanceof AST_Array
&& obj.elements.every(el => !(el instanceof AST_Expansion));

if (
is_spreadless_array(obj)
&& obj.elements.every(el => !el.has_side_effects(compressor))
) {
return obj.elements.length;
}

let fixed;
if (
obj instanceof AST_SymbolRef
&& is_spreadless_array((fixed = obj.definition().fixed_value()))
) {
return fixed.elements.length;
}
}

if (compressor.option("unsafe")) {
var key = this.property;
if (key instanceof AST_Node) {
key = key._eval(compressor, depth);
if (key === this.property)
return this;
}

var exp = this.expression;
if (is_undeclared_ref(exp)) {

var aa;
var first_arg = exp.name === "hasOwnProperty"
&& key === "call"
Expand Down
21 changes: 21 additions & 0 deletions test/compress/evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,27 @@ unsafe_string_bad_index: {
expect_stdout: true
}

safe_array_string_length: {
options = {
reduce_vars: true,
evaluate: true,
}
input: {
const array_ref = [1, leak("side effect")]
console.log(
"Hi!!".length,
[1, 2].length,
array_ref.length,
[id("side eff")]
);
}
expect: {
const array_ref = [1, leak("side effect")]
console.log(4, 2, 2, [id("side eff")]);
}
expect_stdout: "4 2 2 [ 'side eff' ]"
}

prototype_function: {
options = {
evaluate: true,
Expand Down

0 comments on commit 31753d0

Please sign in to comment.