Uglifyjs: switch case elimination does not always take fallthrough into account

Created on 1 Apr 2017  路  17Comments  路  Source: mishoo/UglifyJS

8 cases are reported over 5 MegaFuzz, 3 of which are [Function: __func_<<N>>__] so we've got 5 left to investigate.

Edit: 3 of the cases turns out to be byte-identical, so we are down to 3 cases.

bug

All 17 comments

Case 1 & 2 & 3

(Now I'm worried how random test/ufuzz.js actually is...)

// original code
// (beautified)
var a = 100, b = 10, c = 0;

function f0(isFinite_1) {
    {
        var brake2 = 5;
        while (a++ + --b && --brake2 > 0) {
            if (a++) {
                var brake4 = 5;
                do {
                    {
                        var brake5 = 5;
                        do {
                            switch (typeof NaN != "boolean") {
                              case a++ + typeof foo_7 !== "crap":
                              default:
                                switch (new function() {
                                    +function() {
                                    }();
                                    return Math;
                                }()) {
                                  default:
                                    c = c + 1;
                                    if (c = 1 + c, Infinity, {} % NaN % 24..toString() >= {} && "foo" > (c = c + 1,
                                    NaN)) {
                                        c = 1 + c, (isFinite_1 /= undefined & "bar" >>> {} != NaN) | Infinity == ([ , 0 ].length === 2) != [ , 0 ][1] && undefined;
                                    }

                                  case (c = c + 1) + new function() {
                                        c = 1 + c, 38..toString() | ([ , 0 ].length === 2) / 22 === 38..toString() <= [ , 0 ][1] >>> null >= {} % undefined;
                                        return Math;
                                    }():
                                    {
                                    }
                                    var isNaN_14 = (c = 1 + c, 23..toString() / {} ^ -0 | {} && undefined && "bar" >> undefined - NaN);
                                    break;

                                  case NaN && [ , 0 ][1] < null != {} > 38..toString() + 24..toString() + 38..toString() / ([ , 0 ].length === 2) ? a++ + new function() {
                                        c = 1 + c, [ , 0 ][1] >>> undefined >> true != "foo", (isNaN_14 = -0 <= "bar") >>> [ , 0 ][1] & 24..toString();
                                        return Math;
                                    }() : NaN <= true != 22 || true + undefined && [ , 0 ][1] && 38..toString() - NaN:
                                    switch (c = 1 + c, [ , 0 ][1] % "bar" !== Infinity !== 0, NaN != [ , 0 ][1] ^ Infinity || 25) {
                                      case c = 1 + c, true !== Infinity < {} < ([ , 0 ].length === 2) > undefined & 0 != "bar" === 24..toString():
                                        ;
                                        break;

                                      case c = 1 + c, 24..toString() + 0 !== 0 ^ null ^ [] != "foo" !== (isNaN_14 != 24..toString() > 38..toString()):
                                        ;
                                        break;

                                      case c = 1 + c, [] < undefined >>> ([ , 0 ].length === 2) | {} >= 22 && undefined ^ null == undefined:
                                        ;
                                        break;

                                      case c = 1 + c, 22 === "bar" % -0 % [ , 0 ][1] + false % true ^ NaN & 22:
                                        ;
                                        break;
                                    }
                                    {
                                    }
                                    break;

                                  case (c = c + 1) + (b = a):
                                    {
                                        var brake17 = 5;
                                        do {
                                            c = 1 + c, 23..toString(), Infinity + 22, 23..toString() + -0 >> -0 != Infinity && 25;
                                        } while ((c = 1 + c, true >> -1 > [] | 38..toString() !== 23..toString() == 0 >= undefined >> 38..toString()) && --brake17 > 0);
                                    }
                                    for (var brake19 = 5; (c = 1 + c, ([ , 0 ].length === 2) * 22 !== null % "foo" * 0 || [] && NaN,
                                    "bar") && brake19 > 0; --brake19) {
                                        c = 1 + c, {} >> Infinity / NaN + false === [ , 0 ][1] === null && 38..toString() != "bar";
                                    }
                                    break;
                                }

                              case !function eval_21() {}():
                                {
                                    var brake22 = 5;
                                    while (delete a && --brake22 > 0) {
                                        try {
                                            var decodeURI = (c = 1 + c, "bar" * 38..toString() <= "foo" || -0 === false === NaN % null >> {});
                                        } catch (encodeURIComponent_25) {
                                            c = 1 + c, 0 == 22 - ([ , 0 ].length === 2) >= -0 !== 24..toString() * 38..toString() || undefined >> 22;
                                            c = 1 + c, undefined >>> "foo" && undefined !== 22 > -1 > Infinity - 38..toString() >>> "foo";
                                        } finally {
                                            c = 1 + c, (c = c + 1, null) & 38..toString() !== 0 && null || null << ([ , 0 ].length === 2) & 0;
                                            c = 1 + c, undefined ^ -1 + ([ , 0 ].length === 2) % 25 & null >>> {}, NaN == [];
                                        }
                                    }
                                }
                                var c_31 = !function arguments_33() {
                                }() ? --b + 25 - -0 > 23..toString() !== "foo" / 24..toString() >>> null <= false <= [] : (c = c + 1) + void function bar_34() {
                                }(), undefined_32 = (c = c + 1) + ++a;
                                break;

                              case a++ + b--:
                                switch (function() {
                                    c = 1 + c, null & 23..toString() == undefined !== NaN + 25 & true >>> "foo" != [ , 0 ][1];
                                    c = 1 + c, 23..toString() > "foo" % false || 25 & null ^ 22 ^ null + [];
                                    c = 1 + c, Infinity >= [ , 0 ][1] | NaN < [ , 0 ][1] ^ NaN * null <= (c_31 >>>= [ , 0 ].length === 2 == 23..toString());
                                }()) {
                                  case a++ + typeof foo_39 == "unknown":
                                    {
                                        return c = 1 + c, -0 === ([ , 0 ].length === 2) != false !== 22 === NaN < -0 !== 22 !== "bar";
                                    }
                                    break;

                                  default:
                                    {
                                        var brake41 = 5;
                                        do {
                                            c = 1 + c, 38..toString() * false === "bar", 22 != null != "foo" >= 38..toString() * "foo";
                                        } while ((c = 1 + c, -1 | -0 != undefined << 38..toString() * "bar" & 0 + (c_31 &= 38..toString() <= [])) && --brake41 > 0);
                                    }

                                  case --b + (--b + 0 === 1 ? a : b):
                                    {
                                        return c = 1 + c, -0 ^ NaN || null != 24..toString() === -0 ^ 23..toString() * "foo" ^ undefined;
                                    }
                                    {
                                    }

                                  case (c = c + 1) + 0 === 1 ? a : b:
                                    switch (c = 1 + c, -0 + 0 != -1 || "foo" !== (isFinite_1 |= 25 < {} === 0 === -0)) {
                                      case c = 1 + c, (c = c + 1, 0) << "foo" * Infinity < 38..toString() % NaN - Infinity != 25:
                                        ;

                                      case c = 1 + c, 23..toString() == 24..toString() == 0 ^ 38..toString() - 38..toString() << -0 - [] >= 25:
                                        ;
                                        break;

                                      case c = 1 + c, [] !== Infinity * NaN * Infinity * [ , 0 ][1] !== true ^ {} ^ 22:
                                        ;
                                        break;

                                      case c = 1 + c, 24..toString() - {} + 22 < 24..toString() * (c = c + 1, 24..toString()) - 23..toString() << undefined:
                                        ;
                                        break;
                                    }
                                    c = 1 + c, (isNaN_14 === ([ , 0 ].length === 2) / "foo" | true < 38..toString()) == -0 || 25 % [ , 0 ][1] != Infinity;
                                    break;
                                }
                                break;
                            }
                        } while ((1 === 1 ? a : b) && --brake5 > 0);
                    }
                } while (--b + new function() {
                    return Math;
                }() && --brake4 > 0);
            }
        }
    }
    switch (--b + typeof foo_48 !== "string") {
      default:
      case b = a:
        break;

      case --b + -0 >>> ([ , 0 ].length === 2) < NaN / "foo" | 25 - [] << Infinity ^ 38..toString() * --b + (c = c + 1, 
        true & []) + ([ , 0 ].length === 2) <= "bar" !== (c = c + 1, 22):
        break;

      case 0 === 1 ? a : b:
        break;
    }
}

f0();

function f1(decodeURIComponent) {
    var let_50 = +function() {
    }(), c_51 = --b + (c = c + 1) + b-- ? a++ + new function() {
        !a;
        return Math;
    }() : b != a;
    {
        !function f2(a_54) {
            if (typeof isFinite_56 == "number") {
                !function() {
                    c = 1 + c, [ , 0 ][1] << -0 == 22 && {} <= 22 / 0 ^ 25 >> false;
                }();
            }
            {
                {
                    var brake61 = 5;
                    do {
                        var c_51_63;
                    } while (((c = c + 1) + 0 === 1 ? a : b) && --brake61 > 0);
                }
                --b + (b = a);
            }
        }(--b + a--);
    }
}

f1();

function f3(foo_65) {
    {
        return;
        --b + new function() {
            a++ + [ , 0 ][1] <= -0 >= -0 > 38..toString() || ([ , 0 ].length === 2) >>> 23..toString() ^ NaN && 24..toString() ? b !== a : (c = c + 1) + (a++ + undefined);
            return Math;
        }();
    }
}

f3();

{
    var brake69 = 5;
    while (((a = [], {}) - 0 > false + 0 | -1 > 0 >= [] ^ a++ + typeof encodeURI_70 === "symbol" ? a++ + (a++ + 0 === 1 ? a : b) : --b + 0) && --brake69 > 0) {
        var brake71 = 5;
        while ((a++ + 1 === 1 ? a : b) && --brake71 > 0) {
            var brake72 = 5;
            do {
                a++ + typeof encodeURIComponent_74 == "crap";
            } while ((25 % undefined - undefined < -0 & false / undefined >= ([ , 0 ].length === 2) && undefined,
            ++a) && --brake72 > 0);
        }
    }
}

{
    var brake75 = 5;
    do {
        {
            !function f4(decodeURIComponent_77) {
                --b + (decodeURIComponent_77 !== Infinity == null) | [ , 0 ][1] & 0 !== false != "bar" + null - 38..toString();
                for (var brake79 = 5; ++a && brake79 > 0; --brake79) {
                    (c = c + 1) + (--b + 22 != 24..toString() >>> [ , 0 ][1] >= "foo" !== -1 ^ "bar" >> Infinity | undefined > --b + +function() {
                        c = 1 + c, (decodeURIComponent_77 = null != 25) === NaN - [ , 0 ][1] >>> -1 == 22 / 23..toString() && 23..toString();
                        c = 1 + c, 25 / -0 && (decodeURIComponent_77 === 25 / -0) - "foo" / ([ , 0 ].length === 2) + NaN === false;
                        c = 1 + c, [ , 0 ][1] ^ ([ , 0 ].length === 2) >>> ([ , 0 ].length === 2) & null == 25 + false < ([ , 0 ].length === 2) >> undefined;
                    }());
                }
            }(a++ + a--);
        }
    } while ((c = c + 1) + -a && --brake75 > 0);
}

{
    var brake84 = 5;
    do {
        c = c + 1;
    } while ((a -= [ , 0 ][1] / undefined > "foo" > 0) ^ 0 ^ [ , 0 ].length === 2 == NaN % -0 && --brake84 > 0);
}

console.log(null, a, b, c);

```js
// uglified code
// (beautified)
function f0(t) {
for (var n = 5; a++ + --b && --n > 0; ) {
if (a++) {
var e = 5;
do {
var o = 5;
do {
switch (!0) {
case a++ + typeof foo_7 != "crap":
;

                  case !0:
                    for (var r = 5; delete a && --r > 0; ) {
                        try {
                            c = 1 + c, 38..toString();
                        } catch (a) {
                            c = 1 + c, [ , 0 ].length, 24..toString(), 38..toString(), c = 1 + c;
                        } finally {
                            c = 1 + c, c += 1, null & 0 !== 38..toString() && null || [ , 0 ].length, c = 1 + c,
                            [ , 0 ].length;
                        }
                    }
                    --b, 23..toString(), 24..toString(), c += 1, ++a;
                }
            } while (a && --o > 0);
        } while (--b + new function() {
            return Math;
        }() && --e > 0);
    }
}
switch (--b + typeof foo_48 != "string") {
  default:
  case b = a:
  case --b - 0 >>> (2 === [ , 0 ].length) < NaN | 25 - [] << 1 / 0 ^ 38..toString() * --b + (c += 1,
    !0 & []) + (2 === [ , 0 ].length) <= "bar" !== (c += 1, 22):
  case b:
}

}

function f1(t) {
--b + (c += 1) + b-- && (a++, new function() {
Math;
}());
!function(t) {
"number" == typeof isFinite_56 && function() {
c = 1 + c, [ , 0 ][1];
}();
var n = 5;
do {} while (((c += 1) + 0 === 1 ? a : b) && --n > 0);
--b, b = a;
}((--b, a--));
}

function f3(a) {}

var a = 100, b = 10, c = 0;

f0(), f1(), f3();

for (var brake69 = 5; a = [], ({} - 0 > 0 | !1 >= [] ^ a++ + typeof encodeURI_70 == "symbol" ? a++ + (0 + a++ == 1 ? a : b) : 0 + --b) && --brake69 > 0; ) {
for (var brake71 = 5; (1 + a++ == 1 ? a : b) && --brake71 > 0; ) {
var brake72 = 5;
do {
a++;
} while ([ , 0 ].length, ++a && --brake72 > 0);
}
}

var brake75 = 5;

do {
!function(t) {
--b, [ , 0 ][1], 38..toString();
for (var n = 5; ++a && n > 0; --n) {
c += 1, --b, 24..toString(), [ , 0 ][1], --b, function() {
c = 1 + c, (t = !0) === NaN - [ , 0 ][1] >>> -1 == 22 / 23..toString() && 23..toString(),
c = 1 + c, [ , 0 ].length, c = 1 + c, [ , 0 ][1], [ , 0 ].length, [ , 0 ].length,
[ , 0 ].length;
}();
}
}(a++ + a--);
} while ((c += 1) + -a && --brake75 > 0);

var brake84 = 5;

do {
c += 1;
} while (0 ^ (a -= [ , 0 ][1] / void 0 > "foo" > 0) ^ 2 === [ , 0 ].length == NaN && --brake84 > 0);

console.log(null, a, b, c);

```js
original result:
null 33 254 2418

uglified result:
null 33 254 1818

Case 4

// original code
// (beautified)
var a = 100, b = 10, c = 0;

for (var brake2 = 5; (0 === 1 ? a : b) && brake2 > 0; --brake2) {
    for (var brake4 = 5; typeof Math_5 !== "crap" && brake4 > 0; --brake4) {
        var brake6 = 5;
        do {
            {
                var brake7 = 5;
                do {
                    if ((c = c + 1) + (b /= a)) {
                        var brake9 = 5;
                        while (++a && --brake9 > 0) {
                            var brake10 = 5;
                            do {
                                {
                                    var brake11 = 5;
                                    while ((b /= a) && --brake11 > 0) {
                                        c = 1 + c, 25 >= 0 >>> undefined >>> 22 != (a *= Infinity / 25 <= undefined ^ -0);
                                    }
                                }
                            } while (typeof arguments_13 === "object" && --brake10 > 0);
                        }
                    }
                } while (a++ + new function() {
                    --b + (a !== (a |= 0 >= ([ , 0 ].length === 2) === 23..toString() && true) % ([ , 0 ].length === 2) == 25 >>> 22 << 38..toString());
                    return Math;
                }() && --brake7 > 0);
            }
        } while (Infinity << -1 > 24..toString() | null / NaN | 22 % (c = c + 1, Infinity) && --brake6 > 0);
    }
    var let = a++ + typeof parseFloat !== "crap", decodeURI_15 = (c = c + 1) + (b *= a);
    var arguments_17 = 0 === 1 ? a : b, undefined = --b + a++;
}

console.log(null, a, b, c);

```js
// uglified code
// (beautified)
for (var a = 100, b = 10, c = 0, brake2 = 5; b && brake2 > 0; --brake2) {
for (var brake4 = 5; "crap" != typeof Math_5 && brake4 > 0; --brake4) {
var brake6 = 5;
do {
var brake7 = 5;
do {
if ((c += 1) + (b /= a)) {
for (var brake9 = 5; ++a && --brake9 > 0; ) {
var brake10 = 5;
do {
for (var brake11 = 5; (b /= a) && --brake11 > 0; ) {
c = 1 + c, a *= 1 / 0 <= undefined ^ -0;
}
} while ("object" == typeof arguments_13 && --brake10 > 0);
}
}
} while (a++ + new function() {
return --b, a |= 0 >= (2 === [ , 0 ].length) === 23..toString() && !0, [ , 0 ].length,
38..toString(), Math;
}() && --brake7 > 0);
} while (0 > 24..toString() | NaN | 22 % (c += 1, 1 / 0) && --brake6 > 0);
}
var let = a++ + typeof parseFloat != "crap", decodeURI_15 = (c += 1) + (b *= a), arguments_17 = b, undefined = --b + a++;
}

console.log(null, a, b, c);

```js
original result:
null 4 Infinity 10755

uglified result:
null 3012 Infinity 10755

Case 5

// original code
// (beautified)
var a = 100, b = 10, c = 0;

switch (b = a) {
  default:
    {
        var brake2 = 5;
        while (a++ + (b = a) && --brake2 > 0) {
            var brake3 = 5;
            while (--b + a-- && --brake3 > 0) {
                if (typeof eval_5 == "number") {
                    if (typeof arguments_7 != "string") {
                        {
                            var brake9 = 5;
                            while (+function foo_10() {}() && --brake9 > 0) {}
                        }
                    } else {
                        switch ((c = c + 1) + new function() {
                            return Math;
                        }()) {
                          default:
                          case b = a:
                            break;

                          case --b + 22 >>> 25 * Infinity % -0 >>> 25 != 25 << {} / Infinity ? (c = c + 1) + undefined < null - 0 > "bar" != null & undefined >> null === NaN : [ , 0 ][1]:
                            switch (--b + (b /= a)) {
                              case 38..toString() % 25 || 24..toString() % 25 >> 0 * undefined - Infinity + 24..toString() || (c = c + 1) + (b += a):
                                var Infinity_15 = (c = c + 1) + -a;
                                {
                                    !function f0(arguments_17) {
                                    }((c = 1 + c, "bar" <= "foo" !== "bar" >> 25 & [ , 0 ][1] === -0 / "bar" ^ 0));
                                }
                                break;

                              case --b + a--:
                                {
                                    var brake18 = 5;
                                    do {
                                        {
                                        }
                                    } while ((c = c + 1) + (b += a) && --brake18 > 0);
                                }
                                break;

                              case a++ + [] && NaN !== false == "bar" != "bar" ^ "bar" && 22 >> NaN >> a--:
                                break;

                              case a++ + 0 === 1 ? a : b ? (c = c + 1) + new function() {
                                    a++ + function() {
                                    }();
                                    return Math;
                                }() : b + 1 - .1 - .1 - .1:
                                break;
                            }
                            switch (a++ + b--) {
                              default:
                              case --b + --b:
                                {
                                    c = 1 + c, null || 25 && -1 || 24..toString() == 24..toString(), undefined <= "bar" || [ , 0 ][1];
                                    c = 1 + c, [ , 0 ][1] % 25 | "bar" >= [] <= ([ , 0 ].length === 2) * Infinity && 24..toString() % {};
                                    c = 1 + c, (Infinity_15 <<= Infinity > 24..toString() >> (c = c + 1, Infinity)) !== NaN != Infinity & {} % {};
                                }
                                if (--b + 23..toString() === [] <= [ , 0 ][1] && 23..toString() >> NaN <= undefined >= undefined === "foo") {
                                    c = 1 + c, 24..toString() <= -1 << true !== undefined === (Infinity_15 = undefined / [] >> ([ , 0 ].length === 2) <= 0);
                                } else {
                                    switch (c = 1 + c, "bar" + 25 === null <= undefined < 25 <= ([ , 0 ].length === 2) <= Infinity ^ [ , 0 ][1]) {
                                      case c = 1 + c, -0 % {} >>> [ , 0 ][1] > -0 >> "bar" >> {} & false || [ , 0 ].length === 2:
                                        ;
                                        break;

                                      case c = 1 + c, -1 <= 0 / (c = c + 1, [ , 0 ][1]) && 25 || [] ^ true == true:
                                        ;

                                      case c = 1 + c, Infinity + [ , 0 ][1] / null !== -1 ^ "foo" * true ^ true == 23..toString():
                                        ;
                                        break;

                                      default:
                                        ;
                                    }
                                }
                                break;

                              case false && Infinity < {} <= "foo" | (Infinity_15 = [] / 24..toString() < Infinity & -0):
                                var decodeURI;

                              case -b:
                                for (var brake29 = 5; (b = a) && brake29 > 0; --brake29) {
                                }
                                {
                                    var brake31 = 5;
                                    while (--b + (c = 1 + c, c = c + 1, true % true % true - ([ , 0 ].length === 2)) && --brake31 > 0) {
                                        break;
                                    }
                                }
                                break;
                            }
                            break;

                          case (c = c + 1) + ++a:
                            break;
                        }
                    }
                }
            }
        }
    }

  case a--:
    a++ + true ^ [ , 0 ][1] === NaN * 0 < 23..toString() <= "foo" ^ false >= NaN & a++ + 0 === 1 ? a : b;
    {}
    break;

  case (c = c + 1) + "foo" > "foo" - Infinity >> [ , 0 ][1] / undefined <= true < ([ , 0 ].length === 2) == [] <= a++ + typeof bar_35 === "crap" ? --b + !a : ~b:
    break;

  case (c = c + 1) + (b = a):
    if (b != a) {
        try {
            var decodeURIComponent_39 = typeof parseInt_40 === "special";
        } finally {
            for (var brake41 = 5; (--b + ([ , 0 ].length === 2) - 23..toString() & (c = c + 1,
            []) !== (Infinity_15 == ([ , 0 ].length === 2) >> []) / -1, "bar" === false >>> 25 / "bar" >= null + "bar" >> "foo" == -0 === {}) && brake41 > 0; --brake41) {
                !function f1(decodeURIComponent_43) {
                    function f2(encodeURIComponent_44) {
                        c = 1 + c, encodeURIComponent_44 === "foo" <= Infinity >>> undefined ^ "foo" <= "bar" ^ -1 | false & -1;
                        c = 1 + c, Infinity >>> {} ^ -1 - 38..toString() << (decodeURIComponent_43 != true % ([ , 0 ].length === 2)) || null && undefined;
                    }
                    f2();
                }("foo" === 25 ^ NaN < 0 >>> Infinity ^ true >>> (c = c + 1, [ , 0 ][1]) | a++ + {} * "foo" == true + 24..toString() & true ^ true < undefined > -0 > a++ + a--);
            }
            {
                var brake47 = 5;
                do {
                    {}
                } while ((a++ + true / 25 || -0 >>> 22 / [ , 0 ][1] >= Infinity + -0 && {}) && --brake47 > 0);
            }
        }
    }
    break;
}

if (24..toString() !== -0 <= undefined <= null - 25 == 25 != [] - 24..toString() > a++ + (c = c + 1,
25 < false) !== 22 % {} || 24..toString() !== [ , 0 ][1]) {
    var brake50 = 5;
    while (a++ + 0 && --brake50 > 0) {
        var brake51 = 5;
        while (+function eval_52() {
            {
                return 0 ? [ , 0 ][1] : --b + typeof Infinity_54;
            }
        }() && --brake51 > 0) {
            try {
                for (var brake57 = 5; a++ + (true ? --b + (b = a) : b == a) && brake57 > 0; --brake57) {
                    a++ + 0 === 1 ? a : b;
                }
            } catch (encodeURIComponent_59) {
                {
                    var brake60 = 5;
                    while (--b + new function() {
                        return Math;
                    }() && --brake60 > 0) {
                        {
                            var brake62 = 5;
                            do {
                                c = 1 + c, 23..toString(), {} & Infinity === [ , 0 ][1] == 0 || false <= -1 >= undefined;
                            } while ((c = 1 + c, (decodeURIComponent_39 %= (c = c + 1, 24..toString()) % "bar" * [ , 0 ][1]) >> (c = c + 1,
                            undefined) == [] & 24..toString()) && --brake62 > 0);
                        }
                        var parseFloat = (c = 1 + c, 22 ^ true * (c = c + 1, 23..toString()) ^ 25 && true > [] - {}), a_65 = (c = 1 + c,
                        0 < NaN ^ [ , 0 ].length === 2 === "foo" != 38..toString() >>> undefined ^ {} ^ NaN);
                    }
                }
                switch (!function c_67() {
                    c = c + 1;
                    {
                        return c = 1 + c, undefined % NaN | undefined !== {} !== Infinity | "foo" < 25 ^ {};
                    }
                    {
                        var brake70 = 5;
                        while ((c = 1 + c, null || "foo" <= Infinity <= undefined % 0, false | -0 > true) && --brake70 > 0) {
                            c = 1 + c, 23..toString() * Infinity !== 25 ^ "bar" | {} !== 0 >= -1 + [];
                        }
                    }
                }()) {
                  default:
                    --b + [ , 0 ][1] * 23..toString() > [ , 0 ][1] * ([ , 0 ].length === 2) <= -1 >>> -0 & 23..toString() >>> 22 ^ (c = 1 + c,
                    38..toString() << -1 || [] / 0 | NaN & true || [] !== "foo");
                    try {
                        c = c + 1;
                    } catch (b_75) {
                        c = 1 + c, ([ , 0 ].length === 2) > true - 0 == -1 <= -1 === -1 && 0 > 38..toString();
                        c = 1 + c, 25 !== -0 > ([ , 0 ].length === 2) >= null && -1 << Infinity < 25, -0;
                    }

                  case --b + void b:
                    var isFinite_79 = void a;
                    break;

                  case -a:
                    try {
                        if (c = 1 + c, true !== Infinity << 38..toString() ^ Infinity === "foo" - 24..toString() >> -0 >> undefined) {
                            c = 1 + c, "bar" / -1 & -0 - false >> 38..toString() <= "bar" + Infinity & Infinity;
                        }
                    } catch (encodeURIComponent_83) {
                        c = 1 + c, "foo" || 24..toString() == false <= 25 || 0, 23..toString() & false === undefined;
                        c = 1 + c, (c = c + 1, -0) === 38..toString() >> "bar" || false == undefined ^ 23..toString() * NaN;
                    } finally {
                        c = 1 + c, 0, 0 % (c = c + 1, true) || [ , 0 ][1], NaN || undefined > 25;
                        c = 1 + c, (c = c + 1, 25) !== 0 ^ -1 > NaN + -0 == 23..toString() | 23..toString();
                    }
                    try {
                        for (var brake89 = 5; (c = 1 + c, 24..toString() !== 22 || 23..toString() <= undefined | 23..toString(),
                        [ , 0 ].length === 2 && 22 ^ 25) && brake89 > 0; --brake89) {
                            c = 1 + c, [ , 0 ].length === 2 === null % (c = c + 1, [ , 0 ].length === 2) - false + true >= 23..toString() !== [];
                        }
                    } catch (parseInt_91) {
                        c = 1 + c, Infinity - -0 - 24..toString() || true >> [] + 23..toString(), 22 - Infinity;
                        c = 1 + c, false ^ 38..toString() >> null || -1 & [] % Infinity < true | [ , 0 ][1];
                    } finally {
                        c = 1 + c, 24..toString() >> [] >> -0 / 0 <= {} > 25 + false ^ [ , 0 ].length === 2;
                        c = 1 + c, [] / [ , 0 ][1] - -0 | false + -1 - 38..toString() % [ , 0 ][1] <= undefined;
                    }
                    break;

                  case --b + 0 === 1 ? a : b:
                    for (var brake96 = 5; ((c = 1 + c, (decodeURIComponent_39 *= Infinity >> null) % 0 + 22 << (c = c + 1,
                    23..toString() & 38..toString())) ? (c = 1 + c, -1 - {} ^ {} / Infinity || [] == 25 <= undefined !== "bar") : (c = 1 + c,
                    "bar" <= -1 >> [ , 0 ][1] >= Infinity >> -1 % [] === ([ , 0 ].length === 2) / 38..toString())) && brake96 > 0; --brake96) {
                        var brake97 = 5;
                        do {
                            c = 1 + c, null >>> ([ , 0 ].length === 2) !== undefined % [ , 0 ][1], Infinity < [ , 0 ][1] >= 23..toString() !== true;
                        } while ((c = 1 + c, -1 % 24..toString() >= {} != "foo" && [] & 0 == 38..toString() == NaN) && --brake97 > 0);
                    }
                    break;
                }
            }
        }
    }
} else {
    for (var brake99 = 5; ((c = c + 1) + 24..toString() != false / true & NaN + {} >= -0 / true / {} ? (c = c + 1) + typeof parseFloat_100 == "boolean" : --b + "foo") && brake99 > 0; --brake99) {
        continue;
    }
}

function f3(Math_102) {
    return;
    var Math_102_105 = a++ + --b;
}

f3();

function f4(Infinity_106) {
    function f5(parseFloat_107) {
        c = c + 1;
        if (--b + false) {
            c = c + 1;
        } else {
            c = c + 1;
        }
    }
    f5();
    function f6(Infinity_106_112) {
        {
            return;
            (c = c + 1) + (--b + +a);
        }
        for (var brake114 = 5; --b + --b && brake114 > 0; --brake114) {}
    }
    f6();
    function f7(isFinite_79_116) {
        {
            var brake117 = 5;
            do {
                {
                    return typeof c_119 == "crap";
                }
            } while ((24..toString() - Infinity ^ "bar", NaN / "bar" ^ [ , 0 ][1] > 22 == [] || --b + 0 === 1 ? a : b) && --brake117 > 0);
        }
        c = c + 1;
    }
    f7();
}

f4();

function f8(parseInt_121) {
    for (var brake122 = 5; (c = c + 1) + new function() {
        void function a_123() {
            {
                var brake124 = 5;
                while ((c = c + 1) + +a && --brake124 > 0) {
                    return --b + ++a;
                }
            }
            {
                var brake126 = 5;
                do {
                    a++ + a--;
                } while ((c = c + 1) + (isFinite_79 |= false << [ , 0 ][1] >>> [] << 22 == 24..toString() && undefined <= 23..toString() != [ , 0 ][1]) + void function let_128() {
                    if (c = 1 + c, false ^ 24..toString() === ([ , 0 ].length === 2) ^ 22, [ , 0 ][1] <= 25 != 23..toString() != undefined) {
                        c = 1 + c, 0 ^ NaN > undefined - 23..toString() ^ undefined & Infinity > true !== 22;
                    } else {
                        c = 1 + c, 38..toString() === 24..toString() | 22 !== 38..toString() !== [] && null | 23..toString() * 0;
                    }
                    c = 1 + c, (c = c + 1, 22) | 22 | 22 & [ , 0 ].length === 2 == undefined * 23..toString() & undefined;
                    {
                        var brake133 = 5;
                        while ((c = 1 + c, 23..toString() + false, [] >= true ^ 22 ^ false, "foo" <= 22) && --brake133 > 0) {
                            c = 1 + c, (c = c + 1, [ , 0 ].length === 2) == ([ , 0 ].length === 2) !== NaN > (let_128 != NaN > {}) + Infinity << 24..toString();
                        }
                    }
                }() && --brake126 > 0);
            }
            if ((c = c + 1) + NaN * 25 - 22 / Infinity + true % 38..toString() || [ , 0 ][1] || 25) {
                (c = c + 1) + ++b;
            }
        }();
        return Math;
    }() && brake122 > 0; --brake122) {
        switch (0 === 1 ? a : b) {
          default:
            {
                var brake138 = 5;
                do {
                    var NaN_140 = a++ + (b = a);
                } while ((a++ + void function() {
                    var isFinite_142 = ++a, a_143 = --b;
                    {
                        c = 1 + c, [] && ([ , 0 ].length === 2) * "foo" & -1 % [] || ([ , 0 ].length === 2) > [] ^ -0;
                        c = 1 + c, (decodeURIComponent_39 = false <= false) + (isFinite_142 = 22 != [ , 0 ][1]) % "bar" - -1 >= 0 <= [];
                        c = 1 + c, -1 == undefined == 0 || false / "bar" <= "bar" === false % {};
                        c = 1 + c, "foo" >= null > null || false, [ , 0 ][1] !== -1 >= 22 != 23..toString();
                    }
                }() ? (c = c + 1) + new function() {
                    (c = c + 1) + -0 | Infinity !== "foo" | undefined / 24..toString() >> undefined ^ 25 ^ null;
                    return Math;
                }() : 1 === 1 ? a : b) && --brake138 > 0);
            }

          case a--:
            {
                var brake150 = 5;
                do {
                    {
                        var brake151 = 5;
                        while ((c = c + 1, [] <= [ , 0 ][1]) ^ null / -0 <= -1 << false && --brake151 > 0) {
                            for (var brake152 = 5; b-- && brake152 > 0; --brake152) {
                                for (var brake153 = 5; (--b + 1 === 1 ? a : b) && brake153 > 0; --brake153) {
                                    switch ((c = c + 1) + 24..toString() != ([ , 0 ].length === 2) & [] & undefined && true > [] > Infinity / 23..toString()) {
                                      case (c = c + 1) + (c = 1 + c, 0 >> 22 & "foo" >> 24..toString() != {} | "bar" < 24..toString() > -1) ? (c = 1 + c,
                                        38..toString() || -0 > [] + [ , 0 ][1] <= "foo" || [ , 0 ][1] ^ null >= -1) : (c = 1 + c,
                                        38..toString() >> "bar" === Infinity || "bar" != 0 / -0 < 38..toString() * null):
                                        c = 1 + c, ([ , 0 ].length === 2) <= 22 / -0 == [] * undefined > -1 << 38..toString() ^ [ , 0 ].length === 2;
                                        break;

                                      case --b:
                                        break;

                                      case --b + (b = a):
                                        c = 1 + c, 38..toString() % [ , 0 ][1], ([ , 0 ].length === 2) <= 38..toString(),
                                        true / ([ , 0 ].length === 2) ^ 38..toString() <= NaN;
                                        c = 1 + c, c = c + 1, [ , 0 ].length === 2 | [ , 0 ][1] >> undefined && true;
                                        break;

                                      case (c = c + 1) + (b = a):
                                        c = 1 + c, (c = c + 1, {} || -1) >> {} ^ Infinity / 22 <= ([ , 0 ].length === 2);
                                        c = 1 + c, decodeURIComponent_39 = "foo" || Infinity, 25 !== [ , 0 ][1] <= true || 25 < false >= 25;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                } while (typeof isFinite_79_160 != "string" && --brake150 > 0);
            }
            {
                var brake161 = 5;
                while ((38..toString() >>> -0 >> null % undefined >> 0 < Infinity >>> 23..toString() >> NaN,
                --b + (a++ + [ , 0 ][1] % [ , 0 ][1] < (decodeURIComponent_39 = "bar" & undefined) + 23..toString() & undefined,
                {} == undefined)) && --brake161 > 0) {}
            }
            break;

          case --b + a++ + new function() {
                return Math;
            }() ? a-- ? 38..toString() : function parseInt_163() {
                for (var brake164 = 5; a++ + new function() {
                    return Math;
                }() && brake164 > 0; --brake164) {
                    c = 1 + c, (c = c + 1, Infinity * ([ , 0 ].length === 2)) * -1 + -1 && 38..toString() * -1;
                }
                {
                    return (c = c + 1) + typeof encodeURI_168;
                }
                {
                    var brake169 = 5;
                    while (23..toString() + 22 !== (c = c + 1, undefined) != (c = c + 1, 25 & []) && --brake169 > 0) {
                        var encodeURI_171 = (c = c + 1) + (c = 1 + c, 25 != true * 22 ^ false * 24..toString() !== false * [ , 0 ][1] && 25) ? (c = 1 + c,
                        [ , 0 ][1] >> "foo" != [] - Infinity / 38..toString() <= 38..toString() > [] & 38..toString()) : (c = 1 + c,
                        true < 25 ^ 22 <= null != 24..toString() < 23..toString() ^ 24..toString() << -1);
                    }
                }
            }() : a++ + 1 === 1 ? a : b:
            break;

          case (c = c + 1) + (a++ + new function() {
                --b + !b;
                return Math;
            }()):
            break;
        }
    }
    {
        return void function() {}();
    }
}

f8();

try {
    {
        !function f9(foo) {
            --b + ((c = c + 1) + void a);
            for (var brake176 = 5; a++ + typeof a_177 == "string" && brake176 > 0; --brake176) {
                !function f10(encodeURI_179) {
                    c = c + 1;
                }(typeof Infinity_182);
            }
        }(23..toString());
    }
} finally {
    switch (--b + void function foo() {}()) {
      case 23..toString() + 25 == [ , 0 ][1] % 25 << "bar" + {} < -1 && "foo" || +function decodeURI_184() {
            switch ((c = c + 1) + 25 + 25 != false === 25 % [ , 0 ][1] | [] ^ true <= NaN) {
              case a++ + 23..toString() >= 23..toString() < {} ^ "bar" < 24..toString() < null && 25 >= undefined >= 0 < "foo" + 38..toString() ^ false >>> {} ^ true % 38..toString() !== Infinity:
                c = c + 1;
                if ((c = c + 1, []) | "bar" / true && (c = c + 1, Infinity ^ Infinity)) {}
                break;

              case --b + typeof decodeURI == "number":
                {
                    !function f11(let) {
                    }((c = 1 + c, [] <= undefined <= undefined !== ([ , 0 ].length === 2) >= true >> 0 % {} > -1) ? (c = 1 + c,
                    {} < Infinity ^ true | undefined === [ , 0 ][1] <= true | true * true) : (c = 1 + c,
                    true ^ -1 === false, [ , 0 ][1] == ([ , 0 ].length === 2) | NaN << -0 << NaN));
                }
                {
                    !function f12(foo) {
                        c = 1 + c, Infinity ^ false / false || [ , 0 ][1] && NaN, NaN >= 25 % "foo";
                        c = 1 + c, undefined / ([ , 0 ].length === 2) % 0 % null ^ undefined != undefined === 22 == 25;
                    }(b + 1 - .1 - .1 - .1);
                }
                break;

              case (c = c + 1) + 0 === 1 ? a : b:
                for (var brake194 = 5; (-0 / {} <= 24..toString() || 22 && 22 >= 23..toString() <= NaN || "foo" > a++ + (b = a)) && brake194 > 0; --brake194) {
                    c = c + 1;
                }
                break;

              case [ , 0 ][1] == 25 > 38..toString() > [] >> 38..toString() && -0 == undefined >>> Infinity < (b >>= a):
                if (b = a) {
                    c = 1 + c, true == 38..toString() | 24..toString() < Infinity >> [] >= 38..toString() !== "bar" | true;
                    c = 1 + c, Infinity > NaN / 0 != true ^ (isFinite_79 = true >>> ([ , 0 ].length === 2) >>> 38..toString() >>> "bar");
                    c = 1 + c, 38..toString() + [ , 0 ][1] / undefined < ([ , 0 ].length === 2) & (Infinity_15 ^= [ , 0 ].length === 2 ^ -1 <= undefined === null);
                    c = 1 + c, [] >= {} || 38..toString() >> 25 ^ -0 < 25 * "foo" != true;
                }
                {
                    var brake202 = 5;
                    do {
                        for (var brake203 = 5; (c = c + 1) + 22 + [] + ([ , 0 ].length === 2) + [ , 0 ][1] < (c = c + 1,
                        -0) >>> NaN && -1 && brake203 > 0; --brake203) {
                        }
                    } while (typeof arguments_205 !== "string" && --brake202 > 0);
                }
                break;
            }
        }():
        if (--b) {
            (c = c + 1) + 1 === 1 ? a : b;
        }

      default:
      case 25:
        break;

      case (Infinity_15 == -1 ^ -1) + -0 != [] == "foo" <= -0 * 22 / "bar":
        {
            !function f13(foo_209) {
                function f14(let_210) {
                    function f15(Infinity) {
                    }
                    f15();
                    function f16(encodeURI_211) {
                    }
                    f16();
                }
                f14();
                function f17(isFinite_212) {
                    {
                        return c = 1 + c, [] & NaN >= false || [ , 0 ][1] % 0 + false >> 22 / Infinity;
                    }
                    try {
                        c = 1 + c, [ , 0 ][1] - 24..toString() === 0 >> Infinity | NaN !== false / ([ , 0 ].length === 2) !== "foo";
                    } finally {
                    }
                }
                f17();
                function f18(arguments_216) {
                    c = 1 + c, {} > -1 / false >>> -0 !== 38..toString() === 23..toString() != "foo" / 38..toString();
                    {
                        return c = 1 + c, c = c + 1, {} % -0 || null & 23..toString();
                    }
                }
                f18();
            }(--b + ([ , 0 ].length === 2) >= -0 >= 24..toString() | -1 & -0 || Infinity + 25, Infinity);
        }
        -1 === "bar" & undefined !== null ^ (isFinite_79 %= null == []), 22 | false;
        break;
    }
    c = c + 1;
}

{
    var brake221 = 5;
    while (--b + new function() {
        return Math;
    }() && --brake221 > 0) {
        !function f19(undefined) {
            if (--a) {
                typeof Infinity_15_225;
            } else {}
            {
                var brake227 = 5;
                while ((c = c + 1) + function encodeURIComponent_228() {
                    switch (null >> Infinity + null === [ , 0 ][1] != (a_65 %= -1 >> true >= null % 22) != (c = c + 1) + ++b) {
                      case new function() {
                            return Math;
                        }():
                        {
                            var brake230 = 5;
                            while ((0 <= null || undefined << "foo" !== NaN, null * 24..toString() > [ , 0 ][1]) && --brake230 > 0) {}
                        }
                        {
                            c = 1 + c, decodeURIComponent_39 = 25 == 23..toString() >>> (c = c + 1, NaN) > -0 && 0 - (decodeURIComponent_39 = false <= 38..toString());
                            c = 1 + c, -0 <= 25 && 25 != undefined >> (c = c + 1, 22) == 24..toString() - -1;
                        }

                      case (c = c + 1) + new function() {
                            void function isNaN_235() {
                                c = 1 + c, "bar" <= 24..toString() ^ 25 / 25 >>> 0 === 0 === 23..toString() ^ null;
                                c = 1 + c, null < null >= ([ , 0 ].length === 2) & {} !== 23..toString() | 38..toString() != 38..toString() >> null;
                                c = 1 + c, "bar" || false == {}, "foo" === [ , 0 ][1] - 23..toString() != 38..toString(),
                                23..toString();
                            }();
                            return Math;
                        }():
                        break;

                      case (c = c + 1) + new function() {
                            return Math;
                        }():
                        {
                            c = 1 + c, undefined & [ , 0 ].length === 2 !== false || 25 || NaN != {} == [ , 0 ][1] == [ , 0 ][1];
                            c = 1 + c, "foo" <= null && NaN >> 38..toString() ^ (isFinite_79 = "foo", 22) || 24..toString() > Infinity;
                            c = 1 + c, -0 / false <= {} * 25 == 25 / -1 !== 38..toString() >>> 23..toString();
                            c = 1 + c, (c = c + 1, [ , 0 ][1] != ([ , 0 ].length === 2)) - (c = c + 1, [ , 0 ][1]) <= {} & 24..toString();
                        }
                        break;

                      case new function() {
                            a++ + [ , 0 ][1] ^ NaN !== -1 >>> false >= 22 + [] % ([ , 0 ].length === 2) < [];
                            return Math;
                        }():
                        {
                            var brake244 = 5;
                            do {
                                try {
                                    c = 1 + c, Infinity && 22 & undefined >>> 24..toString() | 25 << 0 & undefined / -1;
                                } catch (undefined_247) {
                                } finally {
                                }
                            } while (a++ + b-- && --brake244 > 0);
                        }
                        {
                            c = 1 + c, 23..toString() != 22 != 23..toString() == NaN <= -0 >= ([ , 0 ].length === 2) > ([ , 0 ].length === 2) / 25;
                        }
                        break;
                    }
                }() && --brake227 > 0) {
                    try {
                        try {
                            try {
                                try {
                                } catch (undefined) {
                                    var Infinity_15 = (c = 1 + c, decodeURIComponent_39 <<= undefined && 22 >>> 24..toString() ^ 0 == 22 ^ [ , 0 ].length === 2 === 24..toString() & NaN), bar_256 = (c = 1 + c,
                                    false & null <= -0 | false % -0 ^ 23..toString() >> null / -1);
                                    {
                                        var brake257 = 5;
                                        do {
                                            c = 1 + c, Infinity ^ undefined >> "foo" >= 22 | (a_65 &= 25 === [ , 0 ][1] ^ NaN == 22);
                                        } while ((c = 1 + c, 38..toString() || null !== ([ , 0 ].length === 2) & 25 >= false >= -0 == undefined | Infinity) && --brake257 > 0);
                                    }
                                }
                            } finally {
                                b |= a;
                                var foo;
                            }
                        } finally {
                            {
                                if (c = 1 + c, true, false > Infinity && Infinity, 23..toString() ^ [ , 0 ][1] !== ([ , 0 ].length === 2),
                                Infinity) {
                                    c = 1 + c, 0 - true <= null > 25, (c = c + 1, 22) << 22 << 24..toString();
                                }
                                {
                                    var brake264 = 5;
                                    while ((c = 1 + c, 24..toString() ^ 23..toString() << [ , 0 ][1] * null > 25 + -0 !== true === "bar") && --brake264 > 0) {
                                        c = 1 + c, null % -0 / null > -1 & (decodeURIComponent_39 ^= [] - "foo" / {} == []);
                                    }
                                }
                                try {
                                    c = 1 + c, 22 || 23..toString() << undefined + false - [ , 0 ][1] <= ([ , 0 ].length === 2) + undefined >= 23..toString();
                                } catch (NaN) {
                                }
                            }
                            for (var brake269 = 5; a++ + typeof bar_270 !== "special" && brake269 > 0; --brake269) {
                                try {
                                    c = 1 + c, "foo" > 22, [ , 0 ][1] ^ [] > ([ , 0 ].length === 2) | Infinity === -1 >= 23..toString();
                                } catch (Infinity) {
                                    c = 1 + c, (Infinity_15 <<= "bar", 23..toString() === [ , 0 ][1] >= NaN) - Infinity != Infinity ^ 23..toString() ^ false;
                                    c = 1 + c, undefined == 0 ^ "bar" !== ([ , 0 ].length === 2) == (c = c + 1, undefined) >= 22 || Infinity;
                                } finally {
                                    c = 1 + c, "bar" == [ , 0 ][1] != [ , 0 ][1] & false ^ [ , 0 ][1] - [], undefined * null;
                                    c = 1 + c, -0 === 24..toString() ^ -1 + [ , 0 ][1] || ([ , 0 ].length === 2) + undefined & true >= [ , 0 ][1];
                                }
                            }
                        }
                    } finally {
                        {
                            var brake277 = 5;
                            while (((--b + (c = 1 + c, null << ([ , 0 ].length === 2) << 25 > 25 * (Infinity_15 = NaN || true,
                            [] === [])) ? (c = 1 + c, undefined | true < false | 0 || (Infinity_15 != 0 - ([ , 0 ].length === 2)) % [ , 0 ][1] && true) : (c = 1 + c,
                            NaN << 0, decodeURIComponent_39 === 0 % undefined || 23..toString() & 0 - "foo" == 23..toString())) ? typeof encodeURI_278 === "number" : a++ + typeof eval_279 == "unknown") && --brake277 > 0) {
                                var brake280 = 5;
                                while (a++ + --b && --brake280 > 0) {
                                    var brake281 = 5;
                                    do {
                                        if (c = 1 + c, false !== -1 * 22 == "foo" != -0 * -1 || true >>> NaN) {
                                            c = 1 + c, (c = c + 1, NaN ^ -0) || (c = c + 1, 38..toString() >>> "bar");
                                        }
                                    } while ((1 === 1 ? a : b) && --brake281 > 0);
                                }
                            }
                        }
                        try {
                            {
                                !function f20(NaN_286) {
                                    c = 1 + c, true === Infinity && undefined * 24..toString() > 0 >>> [] << {} || [];
                                    c = 1 + c, false ^ null !== true & 25 + -1 != 23..toString() / Infinity & 38..toString();
                                }((c = c + 1) + !function() {
                                }());
                            }
                        } finally {
                            c = c + 1;
                            {
                                var brake290 = 5;
                                while (++a && --brake290 > 0) {
                                    var brake291 = 5;
                                    while ((c = 1 + c, 23..toString() !== 24..toString() > 22, true & [ , 0 ].length === 2,
                                    "bar" - 23..toString() - -1) && --brake291 > 0) {
                                        c = 1 + c, (Infinity_15 |= "bar" << []) >> -1 <= ([ , 0 ].length === 2) === -0 - NaN == 38..toString() !== false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }(-0);
    }
}

console.log(null, a, b, c);

```js
// uglified code
// (beautified)
function f3(t) {
return;
}

function f4(t) {
!function(t) {
c += 1, --b, c += 1;
}(), function(t) {
var n = 5;
do {
return "crap" == typeof c_119;
} while (24..toString(), (NaN ^ [ , 0 ][1] > 22 == [] || 0 + --b == 1 ? a : b) && --n > 0);
c += 1;
}();
}

function f8(t) {
for (var n = 5; (c += 1) + new function() {
return function() {
for (var t = 5; (c += 1) + +a && --t > 0; ) {
return --b + ++a;
}
var n = 5;
do {
a++, a--;
} while ((c += 1) + (isFinite_79 |= !1 << [ , 0 ][1] >>> [] << 22 == 24..toString() && void 0 <= 23..toString() != [ , 0 ][1]) + void function() {
c = 1 + c, 24..toString(), [ , 0 ].length, [ , 0 ][1] <= 25 != 23..toString() != void 0 ? (c = 1 + c,
23..toString()) : (c = 1 + c, 38..toString() === 24..toString() | 22 !== 38..toString() !== [] && 23..toString()),
c = 1 + c, c += 1, [ , 0 ].length, 23..toString();
for (;c = 1 + c, 23..toString(), !1; ) {
c = 1 + c, c += 1, [ , 0 ].length, [ , 0 ].length, 24..toString();
}
}() && --n > 0);
(c += 1) + NaN - 0 + !0 % 38..toString() || [ , 0 ][1], c += 1, ++b;
}(), Math;
}() && n > 0; --n) {
switch (b) {
default:
var r = 5;
do {
a++, b = a;
} while ((a++ + void function() {
++a, --b;
c = 1 + c, [] && "foo" * (2 === [ , 0 ].length) & -1 % [] || [ , 0 ].length, c = 1 + c,
decodeURIComponent_39 = !0, 22 != [ , 0 ][1], c = 1 + c, c = 1 + c, [ , 0 ][1],
23..toString();
}() ? (c += 1) + new function() {
return c += 1, 24..toString(), Math;
}() : a) && --r > 0);

      case a--:
        var o = 5;
        do {
            for (var e = 5; !1 ^ (c += 1, [] <= [ , 0 ][1]) && --e > 0; ) {
                for (var i = 5; b-- && i > 0; --i) {
                    for (var g = 5; (1 + --b == 1 ? a : b) && g > 0; --g) {
                        switch ((c += 1) + 24..toString() != (2 === [ , 0 ].length) & [] & void 0 && !0 > [] > 1 / 0 / 23..toString()) {
                          case (c += 1) + (c = 1 + c, 0 & "foo" >> 24..toString() != {} | "bar" < 24..toString() > -1) ? (c = 1 + c,
                            38..toString() || -0 > [] + [ , 0 ][1] <= "foo" || !0 ^ [ , 0 ][1]) : (c = 1 + c,
                            38..toString() >> "bar" == 1 / 0 || "bar" != NaN < null * 38..toString()):
                            c = 1 + c, [ , 0 ].length, 38..toString(), [ , 0 ].length;
                            break;

                          case --b:
                            break;

                          case --b + (b = a):
                            c = 1 + c, 38..toString(), [ , 0 ][1], [ , 0 ].length, 38..toString(), [ , 0 ].length,
                            38..toString(), c = 1 + c, c += 1, [ , 0 ].length, [ , 0 ][1];
                            break;

                          case (c += 1) + (b = a):
                            c = 1 + c, c += 1, [ , 0 ].length, c = 1 + c, decodeURIComponent_39 = "foo", [ , 0 ][1];
                        }
                    }
                }
            }
        } while ("string" != typeof isFinite_79_160 && --o > 0);
        for (var S = 5; 38..toString(), 23..toString(), --b + (a++, [ , 0 ][1], [ , 0 ][1],
        decodeURIComponent_39 = 0, 23..toString(), void 0 == {}) && --S > 0; ) {}
        break;

      case --b + a++ + new function() {
            return Math;
        }() ? a-- ? 38..toString() : function() {
            for (var t = 5; a++ + new function() {
                return Math;
            }() && t > 0; --t) {
                c = 1 + c, -1 * (c += 1, 1 / 0 * (2 === [ , 0 ].length)) - 1 && 38..toString();
            }
            return (c += 1) + typeof encodeURI_168;
        }() : 1 + a++ == 1 ? a : b:
      case (c += 1) + (a++ + new function() {
            return --b, Math;
        }()):
    }
}

}

var a = 100, b = 10, c = 0;

switch (b = a) {
default:
for (var brake2 = 5; a++ + (b = a) && --brake2 > 0; ) {
for (var brake3 = 5; --b + a-- && --brake3 > 0; ) {
if ("number" == typeof eval_5) {
if ("string" != typeof arguments_7) {
var brake9 = 5;
} else {
switch ((c += 1) + new function() {
return Math;
}()) {
default:
case b = a:
break;

                  case 22 + --b >>> NaN >>> 25 != 25 << {} / (1 / 0) ? (c += 1) + void 0 < 0 > "bar" != null & !1 : [ , 0 ][1]:
                    switch (--b + (b /= a)) {
                      case 38..toString() % 25 || 24..toString() % 25 >> NaN + 24..toString() || (c += 1) + (b += a):
                        var Infinity_15 = (c += 1) + -a;
                        c = 1 + c, [ , 0 ][1];
                        break;

                      case --b + a--:
                        var brake18 = 5;
                        do {} while ((c += 1) + (b += a) && --brake18 > 0);
                        break;

                      case a++ + [] && 1 && 22 >> a--:
                      case 0 + a++ == 1 ? a : b ? (c += 1) + new function() {
                            return a++, Math;
                        }() : b + 1 - .1 - .1 - .1:
                    }
                    switch (a++ + b--) {
                      default:
                      case --b + --b:
                        if (c = 1 + c, [ , 0 ][1], c = 1 + c, [ , 0 ][1] % 25 | "bar" >= [] <= (2 === [ , 0 ].length) * (1 / 0) && 24..toString(),
                        c = 1 + c, Infinity_15 <<= 1 / 0 > 24..toString() >> (c += 1, 1 / 0), --b + 23..toString() === [] <= [ , 0 ][1] && 23..toString() >> NaN <= void 0 >= void 0 === "foo") {
                            c = 1 + c, 24..toString(), Infinity_15 = void 0 / [] >> (2 === [ , 0 ].length) <= 0;
                        } else {
                            switch (c = 1 + c, "bar25" === !0 <= (2 === [ , 0 ].length) <= 1 / 0 ^ [ , 0 ][1]) {
                              case c = 1 + c, -0 % {} >>> [ , 0 ][1] > 0 >> {} & !1 || 2 === [ , 0 ].length:
                                break;

                              case c = 1 + c, -1 <= 0 / (c += 1, [ , 0 ][1]) && 25 || !0 ^ []:
                              case c = 1 + c, 1 / 0 + [ , 0 ][1] / null != -1 ^ NaN ^ 1 == 23..toString():
                            }
                        }
                        break;

                      case !1:
                        var decodeURI;

                      case -b:
                        for (var brake29 = 5; (b = a) && brake29 > 0; --brake29) {}
                        for (var brake31 = 5; --b + (c = 1 + c, c += 1, 0 - (2 === [ , 0 ].length)) && --brake31 > 0; ) {
                            break;
                        }
                    }
                    break;

                  case (c += 1) + ++a:
                }
            }
        }
    }
}

case a--:
a++, [ , 0 ][1], 23..toString(), a++;
break;

case (c += 1) + "foo" > NaN >> [ , 0 ][1] / void 0 <= !0 < (2 === [ , 0 ].length) == [] <= a++ + typeof bar_35 === "crap" ? --b + !a : ~b:
break;

case (c += 1) + (b = a):
if (b != a) {
try {
var decodeURIComponent_39 = "special" == typeof parseInt_40;
} finally {
for (var brake41 = 5; --b, [ , 0 ].length, 23..toString(), c += 1, [ , 0 ].length,
!0 === {} && brake41 > 0; --brake41) {
!function(t) {
!function(t) {
c = 1 + c, c = 1 + c, 38..toString(), [ , 0 ].length;
}();
}((c += 1, [ , 0 ][1], a++, 24..toString(), a++, a--));
}
var brake47 = 5;
do {} while ((.04 + a++ || -0 >>> 22 / [ , 0 ][1] >= 1 / 0 && {}) && --brake47 > 0);
}
}
}

if (!1 !== 24..toString() == 25 != [] - 24..toString() > a++ + (c += 1, !1) !== 22 % {} || 24..toString() !== [ , 0 ][1]) {
for (var brake50 = 5; 0 + a++ && --brake50 > 0; ) {
for (var brake51 = 5; +function() {
return --b + typeof Infinity_54;
}() && --brake51 > 0; ) {
try {
for (var brake57 = 5; a++ + (--b + (b = a)) && brake57 > 0; --brake57) {
a++;
}
} catch (t) {
for (var brake60 = 5; --b + new function() {
return Math;
}() && --brake60 > 0; ) {
var brake62 = 5;
do {
c = 1 + c, 23..toString(), [ , 0 ][1];
} while (c = 1 + c, (decodeURIComponent_39 %= (c += 1, 24..toString() % "bar" * [ , 0 ][1])) >> void (c += 1) == [] & 24..toString() && --brake62 > 0);
var parseFloat = (c = 1 + c, 15 ^ !0 * (c += 1, 23..toString()) && !0 > [] - {}), a_65 = (c = 1 + c,
!1 ^ 2 === [ , 0 ].length === "foo" != 38..toString() >>> void 0 ^ {} ^ NaN);
}
switch (!function() {
return c += 1, c = 1 + c, NaN | void 0 !== {} !== 1 / 0 | !1 ^ {};
}()) {
default:
--b, [ , 0 ][1], 23..toString(), [ , 0 ][1], [ , 0 ].length, 23..toString(), c = 1 + c,
38..toString();
try {
c += 1;
} catch (t) {
c = 1 + c, (2 === [ , 0 ].length) > 1 == 1 === -1 && 38..toString(), c = 1 + c,
[ , 0 ].length;
}

              case --b + void 0:
                var isFinite_79 = void 0;
                break;

              case -a:
                try {
                    c = 1 + c, !0 !== 1 / 0 << 38..toString() ^ 1 / 0 == "foo" - 24..toString() >> -0 >> void 0 && (c = 1 + c,
                    38..toString());
                } catch (t) {
                    c = 1 + c, 23..toString(), c = 1 + c, c += 1, -0 == 38..toString() >> "bar" || 23..toString();
                } finally {
                    c = 1 + c, 0 % (c += 1, !0) || [ , 0 ][1], c = 1 + c, c += 1, 23..toString(), 23..toString();
                }
                try {
                    for (var brake89 = 5; c = 1 + c, 22 !== 24..toString() || (23..toString(), 23..toString()),
                    2 === [ , 0 ].length && 15 && brake89 > 0; --brake89) {
                        c = 1 + c, [ , 0 ].length, c += 1, [ , 0 ].length, 23..toString();
                    }
                } catch (t) {
                    c = 1 + c, 1 / 0 - 24..toString() || 23..toString(), c = 1 + c, !1 ^ 38..toString() >> null || [ , 0 ][1];
                } finally {
                    c = 1 + c, 24..toString(), [ , 0 ].length, c = 1 + c, [ , 0 ][1], 38..toString(),
                    [ , 0 ][1];
                }
                break;

              case 0 + --b == 1 ? a : b:
                for (var brake96 = 5; c = 1 + c, ((decodeURIComponent_39 *= 0) % 0 + 22 << (c += 1,
                23..toString() & 38..toString()) ? (c = 1 + c, -1 - {} ^ {} / (1 / 0) || 0 == [] !== "bar") : (c = 1 + c,
                "bar" <= -1 >> [ , 0 ][1] >= 1 / 0 >> -1 % [] === (2 === [ , 0 ].length) / 38..toString())) && brake96 > 0; --brake96) {
                    var brake97 = 5;
                    do {
                        c = 1 + c, [ , 0 ].length, [ , 0 ][1], [ , 0 ][1], 23..toString();
                    } while (c = 1 + c, -1 % 24..toString() >= {} != "foo" && [] & 0 == 38..toString() == NaN && --brake97 > 0);
                }
            }
        }
    }
}

} else {
for (var brake99 = 5; ((c += 1) + 24..toString() != 0 & NaN + {} >= -0 / {} ? (c += 1) + typeof parseFloat_100 == "boolean" : --b + "foo") && brake99 > 0; --brake99) {
continue;
}
}

f3(), f4(), f8();

try {
!function(t) {
--b, c += 1;
for (var n = 5; a++ + typeof a_177 == "string" && n > 0; --n) {
!function(t) {
c += 1;
}();
}
}(23..toString());
} finally {
switch (--b + void 0) {
case 23..toString() + 25 == [ , 0 ][1] % 25 << "bar" + {} < -1 && "foo" || +function() {
switch ((c += 1) + 25 + 25 != 0 === 25 % [ , 0 ][1] | !1 ^ []) {
case a++ + 23..toString() >= 23..toString() < {} ^ "bar" < 24..toString() < null && !0 < "foo" + 38..toString() ^ !1 >>> {} ^ !0 % 38..toString() != 1 / 0:
c += 1, NaN | (c += 1, []) && (c += 1);
break;

          case --b + typeof decodeURI == "number":
            c = 1 + c, [] <= void 0 <= void 0 != (2 === [ , 0 ].length) >= !0 >> 0 % {} > -1 ? (c = 1 + c,
            [ , 0 ][1]) : (c = 1 + c, [ , 0 ][1], [ , 0 ].length), function(t) {
                c = 1 + c, [ , 0 ][1], c = 1 + c, [ , 0 ].length;
            }();
            break;

          case (c += 1) + 0 === 1 ? a : b:
            for (var t = 5; (-0 / {} <= 24..toString() || 22 >= 23..toString() <= NaN || "foo" > a++ + (b = a)) && t > 0; --t) {
                c += 1;
            }
            break;

          case [ , 0 ][1] == 25 > 38..toString() > [] >> 38..toString() && -0 == 0 < (b >>= a):
            (b = a) && (c = 1 + c, 38..toString(), 24..toString(), 38..toString(), c = 1 + c,
            isFinite_79 = !0 >>> (2 === [ , 0 ].length) >>> 38..toString() >>> "bar", c = 1 + c,
            38..toString(), [ , 0 ][1], [ , 0 ].length, Infinity_15 ^= 2 === [ , 0 ].length ^ !1,
            c = 1 + c, [] >= {} || 38..toString());
            var n = 5;
            do {
                for (var r = 5; (c += 1) + 22 + [] + (2 === [ , 0 ].length) + [ , 0 ][1] < (c += 1,
                0) && r > 0; --r) {}
            } while ("string" != typeof arguments_205 && --n > 0);
        }
    }():
    --b && (c += 1);

  default:
  case 25:
    break;

  case (-1 == Infinity_15 ^ -1) - 0 != [] == 0:
    !function(t) {
        !function(t) {
            c = 1 + c, !1 & [] || [ , 0 ][1];
        }(), function(t) {
            c = 1 + c, 38..toString(), 23..toString(), 38..toString(), c = 1 + c, c += 1, {} % -0 || 23..toString();
        }();
    }((--b, [ , 0 ].length, 24..toString())), isFinite_79 %= null == [];
}
c += 1;

}

for (var brake221 = 5; --b + new function() {
return Math;
}() && --brake221 > 0; ) {
!function(t) {
--a;
for (var n = 5; (c += 1) + function() {
switch (0 === [ , 0 ][1] != (a_65 %= !1) != (c += 1) + ++b) {
case new function() {
return Math;
}():
for (var n = 5; null * 24..toString() > [ , 0 ][1] && --n > 0; ) {}
c = 1 + c, decodeURIComponent_39 = 25 == 23..toString() >>> (c += 1, NaN) > -0 && 0 - (decodeURIComponent_39 = !1 <= 38..toString()),
c = 1 + c, c += 1, 24..toString();

          case (c += 1) + new function() {
                return function() {
                    c = 1 + c, 24..toString(), 23..toString(), c = 1 + c, [ , 0 ].length, 23..toString(),
                    38..toString(), 38..toString(), c = 1 + c, [ , 0 ][1], 23..toString(), 38..toString(),
                    23..toString();
                }(), Math;
            }():
            break;

          case (c += 1) + new function() {
                return Math;
            }():
            c = 1 + c, t & 2 === [ , 0 ].length != !1 || 25 || ([ , 0 ][1], [ , 0 ][1]), c = 1 + c,
            24..toString(), c = 1 + c, 38..toString(), 23..toString(), c = 1 + c, c += 1, [ , 0 ][1],
            [ , 0 ].length, c += 1, [ , 0 ][1], 24..toString();
            break;

          case new function() {
                return a++, [ , 0 ][1], [ , 0 ].length, Math;
            }():
            var r = 5;
            do {
                try {
                    c = 1 + c, 24..toString();
                } catch (t) {}
            } while (a++ + b-- && --r > 0);
            c = 1 + c, 23..toString(), 23..toString(), [ , 0 ].length, [ , 0 ].length;
        }
    }() && --n > 0; ) {
        try {
            try {
                try {
                    var r;
                } finally {
                    b |= a;
                }
            } finally {
                c = 1 + c, 23..toString(), [ , 0 ][1], [ , 0 ].length, c = 1 + c, c += 1, 24..toString();
                for (var o = 5; c = 1 + c, 24..toString() ^ 23..toString() << null * [ , 0 ][1] > 25 != !0 === "bar" && --o > 0; ) {
                    c = 1 + c, decodeURIComponent_39 ^= [] - "foo" / {} == [];
                }
                try {
                    c = 1 + c;
                } catch (t) {}
                for (var e = 5; a++ + typeof bar_270 != "special" && e > 0; --e) {
                    try {
                        c = 1 + c, [ , 0 ][1], [ , 0 ].length, 23..toString();
                    } catch (t) {
                        c = 1 + c, r <<= "bar", 23..toString(), [ , 0 ][1], 23..toString(), c = 1 + c, [ , 0 ].length,
                        c += 1;
                    } finally {
                        c = 1 + c, [ , 0 ][1], [ , 0 ][1], [ , 0 ][1], c = 1 + c, -0 === 24..toString() ^ -1 + [ , 0 ][1] || ([ , 0 ].length,
                        [ , 0 ][1]);
                    }
                }
            }
        } finally {
            for (var i = 5; ((--b + (c = 1 + c, null << (2 === [ , 0 ].length) << 25 > 25 * (r = !0,
            [] === [])) ? (c = 1 + c, !1 | t | 0 || (r != 0 - (2 === [ , 0 ].length)) % [ , 0 ][1] && !0) : (c = 1 + c,
            decodeURIComponent_39 === 0 % t || 23..toString() & NaN == 23..toString())) ? "number" == typeof encodeURI_278 : a++ + typeof eval_279 == "unknown") && --i > 0; ) {
                for (var g = 5; a++ + --b && --g > 0; ) {
                    var S = 5;
                    do {
                        c = 1 + c, c = 1 + c, c += 1, c += 1, 38..toString();
                    } while (a && --S > 0);
                }
            }
            try {
                !function(t) {
                    c = 1 + c, c = 1 + c, 23..toString(), 38..toString();
                }(c += 1);
            } finally {
                c += 1;
                for (var f = 5; ++a && --f > 0; ) {
                    for (var l = 5; c = 1 + c, 23..toString(), 24..toString(), [ , 0 ].length, "bar" - 23..toString() - -1 && --l > 0; ) {
                        c = 1 + c, r |= "bar" << [], [ , 0 ].length, 38..toString();
                    }
                }
            }
        }
    }
}(-0);

}

console.log(null, a, b, c);

```js
original result:
null 215 195 5722

uglified result:
null 215 196 12778

Case 5 is a weird one. No uglified code here. Only Node 0.10.x agrees with jxcore/spidermonkey. All other versions of Node produce different results.

case5.js is the original code above with the exact-same-string version of the Function.prototype.toString preamble plus one modification - renamed the variable named let to l3t to test on jxcore. (Side note: I think we should drop "let" from the fuzzer).

$ node773 case5.js 
null 215 195 5218

$ node690 case5.js 
null 215 195 3706

$ node591 case5.js 
null 215 195 7234

$ node421 case5.js 
null 215 195 6226

$ node0_12_9 case5.js 
null 215 195 8746

$ node0_10_41 case5.js 
null 215 196 12778

$ jx case5.js    # mozilla spidermonkey engine
null 215 196 12778

Noticed that Node 0.10.x and jxcore match the uglified result.

Even with the original code in case 1 I get totally different answers for c on IE11. These cases are very odd.

But yes, I think let should probably go as it might create more issues than it's worth, and we are focussing on ES5 anyway.

3 of the cases turns out to be byte-identical
(Now I'm worried how random test/ufuzz.js actually is...)

Should have the fuzzer's rng() use crypto.randomBytes()

I've managed to narrow down case 1 to this so far:

var a = 100, b = 10, c = 0;

function f0(isFinite_1) {
    var brake2 = 5;
    while (a++ + --b && --brake2 > 0) {
        if (a++) {
            var brake4 = 5;
            do {
                var brake5 = 5;
                do {
                    switch (true) {
                        case a++, true:
                        default:
                            c = c + 1;
                        case true:
                    }
                } while (a && --brake5 > 0);
            } while (--b, --brake4 > 0);
        }
    }
}

f0();

console.log(null, a, b, c);
$ cat case1.js | node
null 209 -15 100

$ bin/uglifyjs case1.js -c warnings=0 | node
null 209 -15 0

Case 5 sure looks like a V8 error in Node versions 0.12.x to 7.x.

When case5.js is run through uglifyjs -c and the uglified code run on any node version it produces code whose result agrees with Node 0.10.x and jxcore.

For Case 5, Safari 9.1.3 also agrees with the uglifyjs -c result on all node versions.

@kzc thanks for taking that out.

I've confirmed Case 1+2+3 is a genuine bug in OPT(AST_Switch) and is currently working on a fix.

I'll narrow down Case 5 tomorrow just to see what the V8 bug is - assuming you don't get there first.

For Case 5, V8 in Chrome 57 running the original code agrees with Safari 9.1.3 and uglifyjs -c on all node versions.

Regarding Case 5, if node/v8 versions 4.x - 7.x are run with the --turbo flag (TurboFan?) it will agree with the non-v8 engines and uglifyjs -c result.

Same deal for case #1739:

$ node773 1739.js 
null 120 120 2105

$ node773 --turbo 1739.js 
null 120 118 2625

$ jx 1739.js 
null 120 118 2625

OT: is TurboFan the new or old engine? :ghost:

is TurboFan the new or old engine?

I think it's the new newer one as opposed to the older new one. I can't keep track anymore.

I'll narrow down Case 5 tomorrow just to see what the V8 bug is

I've changed my mind - I don't care what their bug is.

I've changed my mind - I don't care what their bug is.

You are most welcome. :rofl:

Anyway, I've identified the bug in uglify-js for this issue, so let #1752 closes this out eventually and we can move on to the Next Big Thing :tm:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pvdz picture pvdz  路  3Comments

GrosSacASac picture GrosSacASac  路  3Comments

buu700 picture buu700  路  5Comments

hacdias picture hacdias  路  5Comments

alexlamsl picture alexlamsl  路  5Comments