Uglifyjs: Bug: bad rewrite for `if((--b),false)`

Created on 23 Mar 2017  路  10Comments  路  Source: mishoo/UglifyJS

  • Bug report or feature request?
    Bug. Found by UglyFuzzer.

  • uglify-js version (uglifyjs -V)
    uglify-js 2.8.15

I've tried to minimize the case but removing/simplifying it any further makes the error go away. Weird one, but that's what you can expect from a fuzzer. I think it's caused by if ((--b),false) there.

Removing the parenthesis makes the bug go away so perhaps it's related to the grouping operator not being handled properly.

$ cat z.js 
var a = 100, b = 10;

var L1 = 5;
while (--L1 > 0) {
  if ((--b), false) {
    if (b) {
      var ignore = 0;
    }
  }
}

console.log(a, b);
$ node_modules/.bin/uglifyjs z.js -c
WARN: Boolean && always false [z.js:5,6]
for(var a=100,b=10,L1=5;--L1>0;)if(false)var ignore=0;console.log(a,b);
$ node z.js
100 6
$ node_modules/.bin/uglifyjs z.js -c | node
WARN: Boolean && always false [z.js:5,6]
100 10
bug

All 10 comments

Similar case, probably same bug:

var a = 100, b = 10;

function f19() {
  if (++a, false) if (a) if (++a) {  }
}
f19();

console.log(a, b);

Bug. Found by UglyFuzzer.

@qfox - Fantastic!

Bug introduced in [email protected] in cd58635dcc8f74aafa842c2015b294ff4097ba08

@qfox @kzc thanks - investigating.

Confirmed that test case in https://github.com/mishoo/UglifyJS2/issues/1639#issuecomment-288819105 is also caused by cd58635dcc8f74aafa842c2015b294ff4097ba08

The culprit is actually https://github.com/mishoo/UglifyJS2/commit/35a849dc48adf4a7318481f0ff540375ec0e43b2, which turns --b, !1 && b into !1 && --b

-c cascade=false would make this go away.

The culprit is actually 35a849d, which turns --b, !1 && b into !1 && --b

Why did cd58635 bring it to light?

It calls .optimize() instead of .transform(), which means !1 && b won't turn into ~pillar of salt~ !1 just yet, and gave a chance for OPT(AST_Seq) to misbehave.

Is this case related?

var a = 100, b = 10;
a++ && false && a ? 0 : 0;
console.log(a, b);

//  org: 101 10
//  min: 100 10
$ node_modules/.bin/uglifyjs z.js -c 
WARN: Boolean && always false [z.js:2,0]
WARN: Condition always false [z.js:2,0]
WARN: Dropping side-effect-free statement [z.js:2,0]
var a=100,b=10;console.log(a,b);

Because I think it's a different case.

When I change a to 0 the output is the same. Same for removing false there.

@qfox all three cases have the same root cause.

Fix at #1643

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gabmontes picture gabmontes  路  5Comments

PinkyJie picture PinkyJie  路  3Comments

alexlamsl picture alexlamsl  路  4Comments

alexlamsl picture alexlamsl  路  5Comments

JoeUX picture JoeUX  路  3Comments