Uglifyjs: a very old `conditionals` bug, and a `reduce_funcs` bug

Created on 6 Dec 2017  路  6Comments  路  Source: mishoo/UglifyJS

original issue: https://github.com/sveltejs/svelte/issues/985

Bug report or feature request?
bug

ES5 or ES6+ input?
ES5

Uglify version (uglifyjs -V)
uglify-js 3.2.1

JavaScript input

$ cat conditionals_bug.js 
(function(){
    function WTF(x) {
        console.log("WTF", x);
    }
    function foo() {
        return WTF;
    }
    function bar() {
        if (x !== (x = foo())) {
            x(1);
        } else {
            x(2);
        }
    }
    var x = function() {
        console.log("init");
    };
    bar();
    bar();
})();

Expected

$ cat conditionals_bug.js | node
WTF 1
WTF 2

Actual

$ bin/uglifyjs -V
uglify-js 3.2.1
$ cat conditionals_bug.js | bin/uglifyjs -bc conditionals=false | node
WTF 1
WTF 2



md5-f1a5515f956145157a24ed8fdf6a5ab9



$ cat conditionals_bug.js | bin/uglifyjs -bc | node
init
WTF 2



md5-6aea3373a443a97f0c71cd9e7a2c2a44



This bug is as old as the hills...



md5-7cb82c34ddd055c96b7c1ea6b817d44c



$ cat conditionals_bug.js | uglifyjs -bc conditionals=false | node
WTF 1
WTF 2


$ cat conditionals_bug.js | uglifyjs -bc | node
init
WTF 2
```

bug

Most helpful comment

@ekhaled thanks for the test case :+1:

@kzc thanks for testing and code reviews, as usual :wink:

All 6 comments

Bug introduced in v2.4.9 in b521b4b926f7a385ed14ec07bc4b5dad9ebcd93b - four years ago.

@alexlamsl We should get that inter-function call patch into the fuzzer.

Actually, doesn't seem to be the same bug, conditionals=false does not get rid of it

Input:

(function () {

function main(state) {

  var thing = baz(state);

  if (thing !== (thing = baz(state))) {
    console.log("not equal");
  } else {
    console.log("is equal");
  }
}

function baz(s) {
  return s ? foo : bar;
}

function foo() {return 1;}

function bar() {return 2;}

main()

}());

Expected:

$ cat in.js | node
is equal

Actual:

$ bin/uglifyjs -V
uglify-js 3.2.1

$ cat in.js | uglifyjs -bc | node
not equal

$ cat in.js | uglifyjs -bc conditionals=false | node
not equal

$ cat in.js | uglifyjs -bc
!function() {
    function baz(s) {
        return s ? function() {
            return 1;
        } : function() {
            return 2;
        };
    }
    !function(state) {
        var thing = baz(state);
        thing !== (thing = baz(state)) ? console.log("not equal") : console.log("is equal");
    }();
}();

Edit: forgot to mention... reduce_vars=false works

Thanks @ekhaled - two bugs for the price of one!

Another more constrained bug workaround is to use -c reduce_funcs=false:

$ cat in.js | bin/uglifyjs -c reduce_funcs=false --toplevel | node
is equal

For the second bug the last working version was v3.1.6:

$ git checkout v3.1.6 && cat in.js | bin/uglifyjs -c | node
HEAD is now at 2fd927a... v3.1.6
is equal
$ git checkout v3.1.7 && cat in.js | bin/uglifyjs -c | node
Previous HEAD position was 2fd927a... v3.1.6
HEAD is now at f46281e... v3.1.7
not equal

The issue was introduced in a8aa28a7a6c0cb415965d055119956d4333de8fa.

@ekhaled thanks for the test case :+1:

@kzc thanks for testing and code reviews, as usual :wink:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Havunen picture Havunen  路  5Comments

diegocr picture diegocr  路  3Comments

neverfox picture neverfox  路  4Comments

lhtdesignde picture lhtdesignde  路  3Comments

pvdz picture pvdz  路  3Comments