Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ufuzz failure #5215

Closed
alexlamsl opened this issue Dec 10, 2021 · 14 comments · Fixed by #5216
Closed

ufuzz failure #5215

alexlamsl opened this issue Dec 10, 2021 · 14 comments · Fixed by #5216

Comments

@alexlamsl
Copy link
Collaborator

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

switch (--b + (--b + (a && typeof a.undefined == "function" && --_calls_ >= 0 && (25 in [ a++ + (a++ + []), (c = c + 1) + null, (c = c + 1) + {
    length: a++ + undefined,
    length: a++ + [].next,
    [a++ + new function foo(async, a, async_1) {
        this.null >>>= ((2 || "function") && "c" >> "number") >= ([] - "function", undefined >> NaN) & (0 >= Infinity == ([ , 0 ].length === 2 & "number") | ("" >> -5) + (foo && (foo.var = (/[a2][^e]+$/, 
        {}))));
    }()]: delete (("number" !== "bar" !== (c = c + 1, -1)) % ((a &= 22 >> -2) != ("undefined" && null))) ? a-- : (c = c + 1) + (typeof a == "function" && --_calls_ >= 0 && a("number", (c = 1 + c, 
    c = c + 1, (-2 & -0) * ("foo" >> 0))) ? --b + (a && typeof a.a == "function" && --_calls_ >= 0 && (a++ + (a && a.a), 
    a.a)(NaN, (c = 1 + c, 5 % [] != -0 > -2 & (a && ({
        a: a[c = 1 + c, (a %= 5 >> 5) << (this !== /[a2][^e]+$/) & (22 ^ true && "object" << "")]
    } = {
        a: -5 << "c"
    })) * ("c" >> false)), (c = 1 + c, (delete this ^ 23..toString() != null) != 23..toString() / {} <= "b" + "number"))) : (c = c + 1) + (a && typeof a.null == "function" && --_calls_ >= 0 && a.null(true))),
    next: (c = c + 1) + b++,
    then: (38..toString() || undefined) % (null >>> 24..toString()) || (0 == -0) / (0 - NaN)
}, (c = c + 1) + [], a++ + {
    undefined: a++,
    [a]: --b + a++,
    "-2": Infinity,
    async: --b + {
        var: [],
        c: --b + ++a,
        0: (c = c + 1) + (0 === 1 ? a : b),
        ...a,
        [--b + (typeof a == "function" && --_calls_ >= 0 && a())]: (c = c + 1) + (b += a)
    }.a,
    get: new function() {
        {
            var brake2 = 5;
            L11027: do {
                c = c + 1;
            } while (!function() {
            }() && --brake2 > 0);
        }
        (c = c + 1) + ("a" in {
            b: (c = 1 + c, +([] * -2) > ("bar" || "foo") >>> (a && (a.b = "function" - "c"))),
            b: (c = 1 + c, a && (a.async *= (a %= undefined / "bar" <= -0) - (23..toString() + 24..toString() < (23..toString() != [])))),
            get: (c = 1 + c, a && (a.foo >>= ((4 > "bar") / (-2 - "b"), (false | 3) != [ , 0 ][1] + null))),
            [(c = 1 + c, ("" === -5 & "function" === "object") <= ((/[a2][^e]+$/ || "c") | "b" * 38..toString()))]: (c = 1 + c, 
            (5 != Infinity) << 23..toString() + "c" === (a = -2 & this, "bar" | "undefined")),
            next: (c = 1 + c, ((a && (a.static = [] >>> -1)) ^ 23..toString() != 2) & 1 >>> Infinity !== (24..toString() === 0))
        });
        L11028: {
            c = 1 + c, ((23..toString(), 2) | -1 != -3) ^ ("number" || Infinity) >= ("undefined" <= [ , 0 ][1]);
        }
    }()
}.Infinity ], a.undefined)`${--b + (a && a.var)}`))) {
  case (c = c + 1) + 23..toString():
    L11029: {
        c = c + 1;
        {
            var expr10 = (NaN << "foo") / (1 === 23..toString()) === (NaN === -2 === ([ , 0 ][1] == 2));
            L11030: for (var key10 in expr10) {
                c = 1 + c;
                var async = expr10[key10];
                c = c + 1;
            }
        }
        1 === 1 ? a : b;
    }
    break;

  case /[abc4]/.test(((c = c + 1) + (0 === 1 ? a : b) || b || 5).toString()):
    if ((typeof a == "function" && --_calls_ >= 0 && a() || 6).toString()[typeof f1 == "function" && --_calls_ >= 0 && f1(--b + (typeof a == "function" && --_calls_ >= 0 && a(a++ + typeof a, 2)), -3, "foo")]) {} else {
        var brake15 = 5;
        do {
            --b + a;
        } while ((c = c + 1) + (1 === 1 ? a : b) && --brake15 > 0);
    }
    ;
    break;

  default:
    {
        var expr18 = new function async() {
            this.in = (a |= ((a += null / undefined) / (NaN === /[a2][^e]+$/) != (22 * "undefined" != ("object" && null))) % ((Infinity === "c" == /[a2][^e]+$/ <= 23..toString()) > ([] === -2, 
            [ , 0 ][1] * 3))) * ((delete -3 !== (/[a2][^e]+$/ | 22), (async && (async.then |= "function" <= undefined)) == 3 > "function") == (24..toString() ^ Infinity && 0 <= true) % ("foo" >>> 22 ^ (4 ^ undefined))) ^ (((async && (async[(c = c + 1) + (1 in [ (c = 1 + c, 
            ((c = c + 1, 38..toString()) && 24..toString() * "function") & (-3 | "function") * (this == 22)) ])] = NaN === -4 != "undefined" >= -2)) === (-3 ^ 2 ^ "b" * "number")) >= ((async && (async[c = 1 + c, 
            ([ , 0 ][1] || {}) << + -4 <= (1 != 22, -0 === "bar")] += this ^ "number")) <= (null || 38..toString())) + ((0 ^ -1) + (3 || 4)) || (async && (async[(c = c + 1) + ((c = 1 + c, 
            a = (null || false) + (-3 ^ 23..toString()), (undefined == 23..toString()) % (-1 || undefined)) || 8).toString()[c = 1 + c, 
            (2 === -0, -3 !== -0) >= (async && (async[a++ + !function() {
            }()] *= ("undefined" ^ "bar") % ([ , 0 ][1] > Infinity)))]] = ("undefined" > 2) >>> (25 < -0)) || ("foo" >= "object") % (2 <= "foo")) & (c = c + 1, 
            "bar" / 2 > (Infinity | null))) ^ +((-4 !== 3) >>> (NaN ^ 1) ^ (-2 !== -1 ^ "object" == -5), 
            (async && (async[/[abc4]/g.exec(((c = 1 + c, NaN > 1 < ("" === 23..toString()) > (24..toString() !== "foo") >> (-2 >= -0)) || b || 5).toString())] <<= "c" > "a" || -2 == 4)) | (async && (async[a++ + !function() {
            }()] = 0 + undefined << (23..toString() ^ {})))) >> (!([ , 0 ][1] !== true) >> (~"foo", 
            this | 38..toString()) < ((24..toString() != 2) + (async && (async.set = -5 != Infinity)) ^ ("foo" & "undefined") - (c = c + 1, 
            -5)) > ((async && (async.async = 5 + "function" & (24..toString(), "object"))) >>> (null <= true && void -0) | (-3, 
            24..toString()) << (5 && true) <= (-4 % "" <= (0 <= 4)))) ^ (a += (("number" >> "object" ^ (4 ^ [ , 0 ].length === 2)) == null >>> 2 >= (c = c + 1, 
            "a") | void (async && (async.Infinity = 5 * 5)) << (("a" && 0) >>> (3 ^ 22))) + (c = c + 1, 
            +!({} ^ -0)) || (((a = "number" | 25) >>> false * {} != (38..toString() >= [] !== "foo" >>> 38..toString())) >> (async && (async.foo |= "c" === 4), 
            NaN + "number") * ((-5 || this) < delete null)) - (((22 != -4) <= ("foo" !== {})) / (("" >= "number") * (c = c + 1, 
            "")) == (-5 ^ undefined) * (3 % "function") >>> (23..toString() - -0, true + "function"))) > (((-5, 
            4) ^ 22 !== 3 ^ (async && (async.Infinity += "number" > "c")) / ("b" !== undefined)) >>> (([] & 1 ^ (undefined && -2)) < (-"b" && (async && (async.static = {} || undefined)))) > (23..toString() / -1 << ("foo" && Infinity) === ([ , 0 ].length === 2 ^ NaN || Infinity ^ 23..toString()) | 24..toString() >> [ , 0 ][1] ^ [ , 0 ][1] >>> null ^ (async && (async[-a] += (async && (async.var = 4 >= 5)) ^ -5 << /[a2][^e]+$/))) == (async && (async.value += (22 === "") << (null > {}) != (async && (async.NaN = -2 !== -3)) >= (5 >= -5) != ((async && (async.in = ("" | [], 
            ([ , 0 ].length === 2) <= this))) === ("object" << 38..toString()) + (async && (async[c = 1 + c, 
            "foo" === -0, async && (async[c = 1 + c, (async && (async[[ (c = 1 + c, false > 23..toString() && "function" * 4, 
            "function" > 38..toString() === -4 << 2), (c = 1 + c, (-2 | NaN || 23..toString() & -1) < (a /= (-0 != Infinity) >> (22 >> ([ , 0 ].length === 2)))), (c = 1 + c, 
            (a = "b" >>> -1) + (24..toString(), "") !== (-3 >= "c") * (1 ^ "number")) ]] += false !== "c" ^ (async && (async.in += "c" <= 5)))) <= ("bar" << -5 <= (25 <= 1))] = -3 & "c"), 
            c = c + 1, "object" >> -5] |= "foo" + "function"))) & (("a" <= 38..toString()) >> ("c" === 2) < delete -4 - (25 >= false)) % ((c = c + 1, 
            -3 - false) < (4 !== 24..toString() != 2 << this)))));
            this.a = (((a %= "function" % -4) * ("bar" >>> 25) ^ 24..toString() << NaN & "undefined" !== "a") * ((async && (async[a++] = "undefined" != 4 !== delete "bar")) >= ("b" !== -0 | 25 + "object")) <= ("" << 5 < 1 >>> 5 == (Infinity <= /[a2][^e]+$/ || [] % "object")) - (((async && (async.next = this - "a")) !== (c = c + 1, 
            24..toString())) >= (24..toString() ^ [ , 0 ].length === 2 ^ ~false)) != (async && (async[(c = c + 1) + (--b + /[abc4]/g.exec((--b || b || 5).toString()) ? --b + 3 : typeof async == "function" && --_calls_ >= 0 && async((c = 1 + c, 
            (async && (async[~b] += false === 4 | (c = c + 1, "foo"))) <= ([] + 3 ^ 25 != 5))))] = (async && (async[a++ + -2] = -5 * null != "function" >> "a" != (5, 
            5) <= (3 || -3))) + (/[a2][^e]+$/ + Infinity >> (a += "b" << NaN) == (("a" | this) ^ -3 * Infinity)))) << (("a" % 38..toString() | undefined >> 4) + ((25 ^ 1) >> "a" - {}) <= (("foo" !== true) / (([ , 0 ].length === 2) / 38..toString()) != (c = c + 1, 
            async && (async.next = [] | null))))) << !(-(async && (async[-3] = (/[a2][^e]+$/ > "bar", 
            -4 > 25) <= ("b" & true) >> ([ , 0 ].length === 2, 4))) ^ (([] <= 22 || 0 != 5) === (async && (async[async && typeof async.undefined == "function" && --_calls_ >= 0 && async.undefined((c = 1 + c, 
            ("function" == -0 | /[a2][^e]+$/ >>> -2) >= (true / 38..toString() != (async && (async.get += -3 / undefined)))))] += async && (async.a %= "a" !== []) && -0 ^ "function"))) * (("c" ^ "foo" ^ (c = c + 1, 
            5)) <= (1 + "bar" === [ , 0 ][1] * "undefined"))) && !((a = ([ , 0 ][1] < null | (a >>>= -3 !== false)) >= (24..toString() / 1 >= (25 & NaN))) * ((null === {} && [ , 0 ].length === 2 !== 5) <= (23..toString() >= -5) % (false <= {}))) < ((([ , 0 ].length === 2) * 22 ^ {} * "number") != (-3 >= 38..toString()) >>> ("undefined" == 4) & (async && (async[c = 1 + c, 
            async && ({
                length: async.value
            } = {
                length: -4 + "object" < 4 >>> "b" != ("undefined" / ([ , 0 ].length === 2) & ({} & -2))
            })] |= -2 << 5) && 0 == -0) % ((NaN | this) == -"b")) >>> (((async && (async.a = -3 / this)) & (a += [] << 5)) <= (({} || -1) ^ (-3, 
            5)) & (-4 >> 22) * ("c" ^ 24..toString()) !== (Infinity < -3 != (23..toString() === "c"))) <= (a = ((async && (async[--b + (async && async[typeof f0 == "function" && --_calls_ >= 0 && f0(-4, (c = 1 + c, 
            ([ , 0 ][1] <= 4 | ("function" || "function")) >> (22 & -5 || -5 - -4)))])] = (23..toString() > Infinity ^ (c = c + 1, 
            2)) <= (a /= "" && 5) % ("undefined" && "number") | Infinity % "object" <= delete {} <= (a = (async && (async.set += "c" == -1)) < (async && (async.async >>= -2 | {}))))) > -((-2 + 22 ^ (NaN | 1)) * (-1 <= "b" && 23..toString() * [])), 
            (-4 - "undefined" + (2 & 24..toString())) / delete (/[a2][^e]+$/ * 24..toString()) % ((a += (4 | false) > ([ , 0 ][1] == "object")) > (true >= 4 < ("foo" !== "foo"))) !== ((async && (async.value %= "b" == "number")) >= (1 ^ "a") >= ((undefined & 4) !== 24..toString() / false) ^ (("bar" && /[a2][^e]+$/) != true + 23..toString()) <= (2 ^ false) - ("b" != -1))));
            this[/[abc4]/g.exec((--b + (typeof async == "function" && --_calls_ >= 0 && async` ${--b + ("object" in [ typeof async == "function" && --_calls_ >= 0 && async(), a++ + !function() {
            }(), +b, b ^= a, (c = c + 1) + ((foo, bar) => {
            })("number") ])}\\${async}$\`\\${{
                async: --b + (async && typeof async.length == "function" && --_calls_ >= 0 && async.length("function")),
                Infinity: ((c = 1 + c, "object" % "foo" + (-5 && 0) & (-4 | "foo") + (async && (async[c = 1 + c, 
                (async && (async[c = 1 + c, (38..toString() & true) << (async && (async.set = NaN && "undefined")) > "" << 1 << this % []] = "b" - false)) % ("object" & false) <= (23..toString() * true ^ 25 <= /[a2][^e]+$/)] += ([ , 0 ].length === 2) - -2))) || a || 3).toString()
            }.async}${a++ + (typeof f0 == "function" && --_calls_ >= 0 && f0(a += (c = 1 + c, 
            ({} == false) >> (async && ([ async[c = 1 + c, -(-5 ^ -2) & "bar" - ([ , 0 ].length === 2) >>> (-3 !== "object")] ] = [ 22 != -0 ])), 
            "function" <= 22, -5 && "b"), --b + void a, [ , 0 ][1]))}`) || b || 5).toString())] = ((("b" >= [ , 0 ][1]) % ("number" < 25) << ((a = ([ , 0 ].length === 2) < "") >= void 25) ^ (-[] >= ([ , 0 ].length === 2 !== -4) ^ 38..toString() >>> -2 !== ([ , 0 ][1] != -2)) ^ (((c = c + 1, 
            true === -3) && null / "b" | (async && (async.c = "foo" >> "foo"))) ^ (c = c + 1, 
            /[a2][^e]+$/ <= this) >> ((null, "bar") >> (23..toString() !== "foo")))) * void ((NaN < -1 < ("function" !== -4)) * ((-1 ^ 4) / (25 ^ /[a2][^e]+$/)) && ~(([] | 1) / ("a" + 25))) << (((1 !== "bar" ^ (a = undefined > "c")) / (38..toString() & "" ^ (async && (async.set = "object" == 25))) | (38..toString() ^ false | (/[a2][^e]+$/ | "number")) * ((NaN === "") / (-4 === 4)) && ("" * "c" >> ([] & -1) < (undefined - undefined | 38..toString() / 23..toString())) - (-undefined > (23..toString(), 
            "c") || 1 < 0 | ("function" || "object"))) > (async && (async[~b] = ((async && (async.value += (-1 || Infinity, 
            !-4))) | 24..toString() << 2 === "c" >>> "bar") <= ((Infinity | -5) >= (-0 < true)) / (async && (async.undefined -= 22 >>> false >>> ([ , 0 ][1], 
            "number"))) <= ((async && (async[void a] += Infinity <= /[a2][^e]+$/ == (false !== "b"))) + ((2 !== 4) >>> ("object" & "b")) >= ((async && (async.null <<= 3 / this || 0 * 23..toString())) >= ([] / true > ([ , 0 ][1] ^ 0)))))))) % ((c = c + 1, 
            (async && (async[a = (c = 1 + c, ("function" <= [ , 0 ][1] ^ 1 > -3) !== (undefined && undefined) + ("foo" + {}))] ^= (-2 != 23..toString()) >>> (async && (async[c = 1 + c, 
            void ((-5 === "undefined") >= -1 >> 4)] = 5 | -0)))) !== ("a" & [ , 0 ].length === 2 && true - 3)) % (((async && ([ async.foo ] = [ "foo" > "c" ])) + (null === "foo"), 
            ("function" == 3) >= ("" >= "foo")) / (c = c + 1, async && (async.Infinity = ("b", 
            true)) || async && (async.undefined = ([], "function")))) - ((async && (async.set += (-2 > 4, 
            "number" <= NaN) !== (-3 >= true) / (NaN - -4) == ("b" % "number" * (0 ^ -1) === (0 << "a") * (2 >= 0)))) << ((-5 && Infinity || "object" % -1 || ("object" > [ , 0 ][1]) / (-2 >> NaN)) ^ (([ , 0 ][1] ^ undefined) % ("object" * 25) ^ (NaN > 25 ^ "b" + 24..toString())))) > ((async && (async[a++ + async] = 23..toString() / [ , 0 ][1] == ("a" || this) !== ~("number" || -4))) < (("b" + NaN && false >= "function") > (3 == 5) / (NaN | /[a2][^e]+$/)) ^ ((-4 / -5 == (a /= -0 || null)) << ("" >= "a" <= (24..toString() && undefined))) / ((23..toString() !== undefined || 0 ^ NaN) ^ 3 === -2 == (async && (async.a >>>= "" ^ "c")))) * (+(25 >>> -4) >>> ((5, 
            "undefined") || "object" & 1) & !((c = c + 1, 1) * (c = c + 1, "foo")) | ((false || "foo") << [] % "a" & [] >>> ([ , 0 ].length === 2) << (true !== Infinity)) >= (0 != 5 == ("function" != false) == (async && (async.b += 3 << -2)) >>> !false)));
            --a;
            {
                var brake20 = 5;
                do {
                    c = c + 1;
                } while (typeof f0 == "function" && --_calls_ >= 0 && f0() && --brake20 > 0);
            }
            L11031: for (var brake22 = 5; (a = (c = c + 1) + (async && async[--b + {
                set: a++ + /[abc4]/.test(((c = 1 + c, (([ , 0 ].length === 2) << 25) % ("bar" > -5) <= (async && (async.get |= (async && (async[c = 1 + c, 
                "a" % 2 % (async && ([ async[c = 1 + c, delete (async && (async["number" in {}] = (async && (async[c = 1 + c, 
                (async && (async[c = 1 + c, (a = ("b" == 38..toString()) + (Infinity && 0)) | (-2 | "number") / ("number" || "object")] = 0 ^ 3)) % (4 == Infinity) << ((this || -0) << 2 * null)] += NaN >> null)) >>> (c = c + 1, 
                5)))] ] = [ -0 << 2 ])) <= (async && (async[c = 1 + c, ("function" === 23..toString() && (0 || false)) === (async && (async[c = 1 + c, 
                (-1 | 38..toString()) <= (-4 || "a") ^ ("foo" == 24..toString()) <= 4 >> 24..toString()] += true * -0)) << (24..toString() ^ [ , 0 ][1])] = 22 % Infinity)) % ("object" === 24..toString())] = Infinity | 2)) ^ [ , 0 ][1] <= "object"))) || b || 5).toString()),
                set: (c = c + 1) + ((c = 1 + c, a &= (delete (25 % 5), Infinity > "undefined" <= (-5, 
                this))) || 6).toString()[c = 1 + c, c = c + 1, true / undefined >= (null | 2)],
                1.5: 22,
                c: (c = c + 1) + {
                    3: (c = 1 + c, ([ , 0 ].length === 2 || -2) * (2 ^ -0) | (false < {}) - ("a", 3)),
                    [(c = 1 + c, (async && (async[async] += -5 >>> NaN == (-0 !== this))) - ((-5 === "function") + ("" << -2)))]: (c = 1 + c, 
                    ((this < {}) - (undefined <= 25)) / (a += (-5 == null) > -1 * 24..toString())),
                    [(c = 1 + c, (false != 25 || delete "foo") | (3 & -4) + (false << "object"))]: (c = 1 + c, 
                    void {} === (async && (async[c = 1 + c, (async && (async.async <<= (23..toString() || 23..toString()) <= (38..toString() || /[a2][^e]+$/))) == (c = c + 1, 
                    a = Infinity % 38..toString())] &= [] | "bar")) != (25 << [] | ("object" || -0)))
                }[c = 1 + c, a >>>= (5 * 1 ^ 2 & -1) < (NaN >> 38..toString()) / (-5 < "function")]
            }[--b + /[abc4]/.test(((c = c + 1) + (c = 1 + c, (async && (async.async = (-0 ^ 38..toString()) >> ([ , 0 ][1] & 4))) | (async && (async[async && async[c = 1 + c, 
            (async && (async.value >>= 1 >>> Infinity < (c = c + 1, 5))) !== (0 << {}) % ("c" ^ 22)]] = null / -5 / (23..toString() == "a")))) || b || 5).toString())]])) && brake22 > 0; --brake22) {
                var brake23 = 5;
                do {
                    (c = c + 1) + async;
                } while (-(23..toString() - -2 > (async && (async[c = 1 + c, +4 << ("function" >> false) >> ((Infinity, 
                this) | 38..toString() * 2)] = "object" || -2)) < (async && (async.foo = (-4 >= -1) >>> (false >> -2)))) && --brake23 > 0);
            }
        }();
        for (var key18 in expr18) {
            c = 1 + c;
            var bar = expr18[key18];
            {
                var brake25 = 5;
                L11032: do {
                } while ((/[a2][^e]+$/ ^ /[a2][^e]+$/) * ("object" >= 22) <= (-1 >> 4) + ("c" >>> "bar") && --brake25 > 0);
            }
        }
    }
    var yield_2;

  case b <<= a:
    {
        var brake28 = 5;
        do {
            {
                var expr29 = [ (c = c + 1) + (b += a) ];
                for (let key29 of expr29) {
                    c = 1 + c;
                    var bar_1 = expr29[key29];
                    if (!((([ , 0 ].length === 2) >= -3 ^ "function" - Infinity) <= ((-0 ^ [ , 0 ].length === 2) != {} <= "undefined"))) {
                        var arguments;
                    } else {
                        var brake32 = 5;
                        do {
                            a++ + (a++ + (24..toString() in [ --b + (0 === 1 ? a : b), a++ + (typeof f0 == "function" && --_calls_ >= 0 && f0(-0)) ]) || 7).toString()[yield_2 && typeof yield_2.set == "function" && --_calls_ >= 0 && yield_2.set(b + 1 - .1 - .1 - .1)];
                        } while (key29 && key29.foo && --brake32 > 0);
                    }
                }
            }
        } while (typeof (--b + --a) && --brake28 > 0);
    }
    break;
}

{
    var brake34 = 5;
    do {
        var NaN_1 = (c = c + 1) + (typeof f0 == "function" && --_calls_ >= 0 && f0([ , 0 ].length === 2, b++)), b_2 = a++ + (("" | 24..toString()) >>> -"bar" && (b_2 && (b_2[(c = c + 1) + ((c = 1 + c, 
        +({} | [], {} !== "number")) || a || 3).toString()] += undefined & "b" | 23..toString() >> "bar")));
    } while ((({
        static: bar,
        [(c = c + 1) + (((38..toString() ^ 23..toString()) === (yield_2 && ([ yield_2.in ] = [ 22 / [] ]))) >= (b_2 && ([ b_2[--b + (0 === 1 ? a : b)] ] = [ 0 / [ , 0 ][1] === 1 / -4 ])))]: async_2,
        "\t": await
    }, async, foo) => ({
        [--b + (yield_2 && yield_2[{
            null: [ typeof f1 == "function" && --_calls_ >= 0 && f1((c = 1 + c, (c = c + 1, 
            23..toString() && "bar") & (2 ^ -2 && true >>> 23..toString()))), b &= a, 1 === 1 ? a : b ].Infinity,
            value: --b + ((25 % 4 ^ 0 >= "b") != (async && (async[((c = 1 + c, "number" >>> "function" >> (c = c + 1, 
            "") <= ({} >>> "function") - ({} >> "undefined")) || a || 3).toString()] = NaN + "function" - "c" % this))),
            done: --b + (typeof f1 == "function" && --_calls_ >= 0 && f1`${a++ + (bar && bar.null)}${--b + (typeof foo == "function" && --_calls_ >= 0 && foo())}${+function() {
            }()}$${22 in {
                null: (c = 1 + c, true % NaN / (c = c + 1, -0) !== ((async && (async.var = "a" >> -2)) == 0 << 2))
            }}${a++}`)
        }])]: a++ + {}.Infinity,
        [NaN_1 && typeof NaN_1.foo == "function" && --_calls_ >= 0 && NaN_1.foo(-0)]: --b + b--,
        value: --b + --b
    }))({
        undefined: 1,
        [(c = c + 1) + delete (({} < -2 && (yield_2 && (yield_2.then >>= (23..toString(), 
        -1)))) >>> ("object" - /[a2][^e]+$/ && null - []))]: -2
    }) && --brake34 > 0);
}

console.log(null, a, b, c, Infinity, NaN, undefined);
// uglified code
// (beautified)
var _calls_ = 10, a = 100, b = 10, c = 0;

switch (--b + (--b + (a && "function" == typeof a.undefined && 0 <= --_calls_ && (a++, 
a++, c += 1, c += 1, a++, a++, a++, new function foo(async, a, async_1) {
    this.null >>>= !0 & (0 == (2 === [ , 0 ].length & "number") | 0 + (foo && (foo.var = {})));
}(), c += 1, a &= 0, a--, c += 1, b++, 38..toString(), 24..toString(), c += 1, a++, 
a++, --b, a++, --b, {
    var: [],
    c: --b + ++a,
    0: (c += 1) + b,
    ...a,
    [--b + ("function" == typeof a && 0 <= --_calls_ && a())]: (c += 1) + (b += a)
}.a, new function() {
    for (var brake2 = 5; c += 1, 0 < --brake2; ) {}
    c = 1 + (c += 1), a && (a.b = NaN), c = 1 + c, a && (a.async *= (a %= !1) - (23..toString() + 24..toString() < (23..toString() != []))), 
    c = 1 + c, a && (a.foo >>= !0), c = 1 + c, 38..toString(), c = 1 + c, 23..toString(), 
    c = 1 + c, (a = -2 & this) && (a.static = [] >>> -1), 23..toString(), 24..toString(), 
    c = 1 + c, 23..toString();
}(), a.undefined)`${--b + (a && a.var)}`))) {
  case (c += 1) + 23..toString():
    c += 1;
    var key10, expr10 = 0 / (1 === 23..toString()) === !0;
    for (key10 in expr10) {
        var c = 1 + c, async = expr10[key10];
        c += 1;
    }
    break;

  case /[abc4]/.test(((c += 1) + b || b || 5).toString()):
    if (!("function" == typeof a && 0 <= --_calls_ && a() || 6).toString()["function" == typeof f1 && 0 <= --_calls_ && f1(--b + ("function" == typeof a && 0 <= --_calls_ && a(a++ + typeof a, 2)), -3, "foo")]) {
        for (var brake15 = 5; --b, (c += 1) + a && 0 < --brake15; ) {}
    }
    break;

  default:
    var key18, yield_2, expr18 = new function async() {
        this.in = (a |= ((a += NaN) / !1 != 1) % (0 < (0 == /[a2][^e]+$/ <= 23..toString()))) * (0 == (async && (async.then |= !1)) == (24..toString() ^ 1 / 0 && !0) % 4) ^ ((-1 === (async && (async[(c += 1) + (1 in [ (c = 1 + c, 
        c += 1, (38..toString() && "function" * 24..toString()) & -3 * (22 == this)) ])] = !1))) >= 2 + ((async && (async[c = 1 + c, 
        {} << -4 <= !1] += "number" ^ this)) <= 38..toString()) || (async && (async[(c += 1) + (c = 1 + c, 
        a = !1 + (-3 ^ 23..toString()), ((null == 23..toString()) % -1 || 8).toString()[c = 1 + c, 
        (async && (async[a++ + !0] *= NaN)) <= !0])] = 0) || NaN) & (c += 1, !1)) ^ +((async && (async[/[abc4]/g.exec((c = 1 + c, 
        (!1 < ("" === 23..toString()) > ("foo" !== 24..toString()) >> !1 || b || 5).toString()))] <<= !0)) | (async && (async[a++ + !0] = NaN << (23..toString() ^ {})))) >> (!1 >> (this | 38..toString()) < ((2 != 24..toString()) + (async && (async.set = !0)) ^ 0 - (c += 1, 
        -5)) > ((async && (async.async = "5function" & (24..toString(), "object"))) >>> void 0 | 24..toString() << !0 <= !1)) ^ (a += ((4 ^ 2 === [ , 0 ].length) == (c += 1, 
        "a") <= 0 | void (async && (async.Infinity = 25)) << 0) + (c += 1, +!(-0 ^ {})) || (((a = 25) >>> !1 * {} != (38..toString() >= [] !== "foo" >>> 38..toString())) >> !0 * (async && (async.foo |= !1), 
        "NaNnumber")) - ((!0 <= ("foo" !== {})) / (!1 * (c += 1, "")) == NaN >>> (23..toString(), 
        !0 + "function"))) > ((5 ^ (async && (async.Infinity += !0)) / !0) >>> ((1 & [] ^ void 0) < NaN) > (23..toString() / -1 << 1 / 0 === (2 === [ , 0 ].length ^ NaN || 1 / 0 ^ 23..toString()) | 24..toString() >> 0 ^ 0 ^ (async && (async[-a] += -5 ^ (async && (async.var = !1))))) == (async && (async.value += !1 << ({} < null) != !0 <= (async && (async.NaN = !0)) != ((async && (async.in = (2 === [ , 0 ].length) <= this)) === ("object" << 38..toString()) + (async && (async[c = 1 + c, 
        async && (async[c = 1 + c, (async && (async[[ (c = 1 + c, 23..toString(), 38..toString() < "function" === -16), (c = 1 + c, 
        -2 < (a /= !0 >> (22 >> (2 === [ , 0 ].length)))), (c = 1 + c, (a = 0) + (24..toString(), 
        "") !== 0) ]] += !0 ^ (async && (async.in += !1)))) <= !0] = 0), c += 1, 0] |= "foofunction"))) & (("a" <= 38..toString()) >> !1 < 0) % (c += 1, 
        -3 < (4 !== 24..toString() != 2 << this))))), this.a = ((0 * (a %= NaN) ^ 24..toString() << NaN & !0) * (1 <= (async && (async[a++] = !1))) <= (0 == [] % "object") - (((async && (async.next = this - "a")) !== (c += 1, 
        24..toString())) >= (24..toString() ^ 2 === [ , 0 ].length ^ -1)) != (async && (async[(c += 1) + (--b + /[abc4]/g.exec((--b || b || 5).toString()) ? 3 + --b : "function" == typeof async && 0 <= --_calls_ && async((c = 1 + c, 
        (async && (async[~b] += !1 | (c += 1, "foo"))) <= ([] + 3 ^ !0))))] = (async && (async[a++ - 2] = !1)) + (/[a2][^e]+$/ + 1 / 0 >> (a += 0) == (("a" | this) ^ -1 / 0)))) << (("a" % 38..toString() | 0) + (24 >> "a" - {}) <= (!0 / ((2 === [ , 0 ].length) / 38..toString()) != (c += 1, 
        async && (async.next = null | []))))) << !(-(async && (async[-3] = !0)) ^ (([] <= 22 || !0) === (async && (async[async && "function" == typeof async.undefined && 0 <= --_calls_ && async.undefined((c = 1 + c, 
        (!0 / 38..toString() != (async && (async.get += NaN))) <= 0))] += async && (async.a %= "a" !== []) && 0))) * ((0 ^ (c += 1, 
        5)) <= !1)) && !((a = (!1 | (a >>>= !0)) >= (0 <= +24..toString())) * ((null === {} && 2 === [ , 0 ].length !== 5) <= (-5 <= 23..toString()) % (!1 <= {}))) < ((22 * (2 === [ , 0 ].length) ^ "number" * {}) != (38..toString() <= -3) >>> !1 & (async && (async[c = 1 + c, 
        async && ({
            length: async.value
        } = {
            length: 0 != ("undefined" / (2 === [ , 0 ].length) & -2 & {})
        })] |= -64) && !0) % (NaN == (NaN | this))) >>> (((async && (async.a = -3 / this)) & (a += [] << 5)) <= (5 ^ {}) & -1 * ("c" ^ 24..toString()) !== (0 != ("c" === 23..toString()))) <= (async && (async[--b + (async && async["function" == typeof f0 && 0 <= --_calls_ && f0(-4, (c = 1 + c, 
        0))])] = (23..toString() > 1 / 0 ^ (c += 1, 2)) <= (a /= "") % "number" | !1 <= (a = (async && (async.set += !1)) < (async && (async.async >>= -2 | {})))), 
        a = (NaN + (2 & 24..toString())) / (24..toString(), !0) % (!1 < (a += !0)) != (1 <= (async && (async.value %= !1)) >= (0 != 24..toString() / !1) ^ (/[a2][^e]+$/ != !0 + 23..toString()) <= 1)), 
        this[/[abc4]/g.exec((--b + ("function" == typeof async && 0 <= --_calls_ && async` ${--b + ("object" in [ "function" == typeof async && 0 <= --_calls_ && async(), a++ + !0, +b, b ^= a, (c += 1) + void 0 ])}\\${async}$\`\\${[ --b + (async && "function" == typeof async.length && 0 <= --_calls_ && async.length("function")), (c = 1 + c, 
        (NaN & -4 + (async && (async[c = 1 + c, (async && (async[c = 1 + c, (!0 & 38..toString()) << (async && (async.set = NaN)) > 0 << this % []] = NaN)) % 0 <= (!0 * 23..toString() ^ !1)] += (2 === [ , 0 ].length) - -2)) || a || 3).toString()) ][0]}${a++ + ("function" == typeof f0 && 0 <= --_calls_ && f0(a += (c = 1 + c, 
        async && ([ async[c = 1 + c, -5 & "bar" - (2 === [ , 0 ].length) >>> !0] ] = [ !0 ]), 
        "b"), --b + void 0, 0))}`) || b || 5).toString())] = (void 0 * (NaN << (void 0 <= (a = (2 === [ , 0 ].length) < "")) ^ ((2 === [ , 0 ].length !== -4) <= -[] ^ 38..toString() >>> -2 !== !0) ^ (c += 1, 
        !1 ^ (c += 1, (/[a2][^e]+$/ <= this) >> ("bar" >> ("foo" !== 23..toString()))))) << (((!0 ^ (a = !1)) / ("" & 38..toString() ^ (async && (async.set = !1))) | NaN * (!1 ^ 38..toString() | 0) && (NaN >> (-1 & []) < (NaN | 38..toString() / 23..toString())) - (23..toString(), 
        0)) > (async && (async[~b] = ((async && (async.value += !1)) | 24..toString() << 2 == 0) <= !1 / (async && (async.undefined -= 22)) <= ((async && (async[void 0] += !1)) + 1 >= ((async && (async.null <<= 3 / this || 0 * 23..toString())) >= (0 < [] / !0))))))) % (c += 1, 
        ((async && (async[c = 1 + c, a = 1 !== void 0 + "foo" + {}] ^= (-2 != 23..toString()) >>> (async && (async[void (c = 1 + c)] = 5)))) !== ("a" & 2 === [ , 0 ].length && -2)) % (async && (async.foo = [ !0 ][0]), 
        !0 / (c += 1, async ? async.Infinity = !0 : async && (async.undefined = "function"))) - ((async && (async.set += !1)) << (0 ^ "b" + 24..toString())) > ((async && (async[a++ + async] = 23..toString() / 0 == "a" !== -1)) < !1 ^ ((.8 == (a /= null)) << (!1 <= (24..toString() && void 0))) / ((void 0 !== 23..toString() || 0) ^ 0 == (async && (async.a >>>= 0)))) * (0 & (c += 1, 
        c += 1, !0) | ("foo" << [] % "a" & [] >>> (2 === [ , 0 ].length) << !0) >= (1 == (async && (async.b += 3 << -2)) >>> !0))), 
        --a;
        for (var brake20 = 5; c += 1, "function" == typeof f0 && 0 <= --_calls_ && f0() && 0 < --brake20; ) {}
        for (var brake22 = 5; (a = (c += 1) + (async && async[--b + {
            set: a++ + /[abc4]/.test((c = 1 + c, (((2 === [ , 0 ].length) << 25) % !1 <= (async && (async.get |= !1 ^ (async && (async[c = 1 + c, 
            NaN % (async && ([ async[c = 1 + c, async && (async["number" in {}] = (async && (async[c = 1 + c, 
            (async && (async[c = 1 + c, NaN | (a = +("b" == 38..toString()))] = 3)) % !1 << ((this || -0) << 0)] += 0)) >>> (c += 1, 
            5)), !0] ] = [ 0 ])) <= (async && (async[c = 1 + c, ("function" === 23..toString() && !1) === (async && (async[c = 1 + c, 
            (-1 | 38..toString()) <= -4 ^ ("foo" == 24..toString()) <= 4 >> 24..toString()] += -0)) << (0 ^ 24..toString())] = 22)) % ("object" === 24..toString())] = 2)))) || b || 5).toString())),
            set: (c += 1) + (c = 1 + c, ((a &= !1 <= this) || 6).toString()[c = 1 + c, c += 1, 
            !1]),
            1.5: 22,
            c: (c += 1) + {
                3: (c = 1 + c, 2 * (2 === [ , 0 ].length || -2) | (!1 < {}) - 3),
                [(c = 1 + c, +(async && (async[async] += -5 >>> NaN == (-0 !== this))))]: (c = 1 + c, 
                ((this < {}) - !1) / (a += -1 * 24..toString() < !1)),
                [1]: (c = 1 + (c = 1 + c), async && (async[c = 1 + c, (async && (async.async <<= (23..toString() || 23..toString()) <= (38..toString() || /[a2][^e]+$/))) == (c += 1, 
                a = 1 / 0 % 38..toString())] &= "bar" | []), !1 != (25 << [] | "object"))
            }[c = 1 + c, a >>>= 7 < (NaN >> 38..toString()) / !1]
        }[--b + /[abc4]/.test(((c += 1) + (c = 1 + c, (async && (async.async = (-0 ^ 38..toString()) >> 0)) | (async && (async[async && async[c = 1 + c, 
        (async && (async.value >>= 1 < (c += 1, 5))) !== (0 << {}) % 22]] = -0 / ("a" == 23..toString())))) || b || 5).toString())]])) && 0 < brake22; --brake22) {
            for (var brake23 = 5; c += 1, -(23..toString() - -2 > (async && (async[c = 1 + c, 
            4 >> (this | 2 * 38..toString())] = "object")) < (async && (async.foo = 0))) && 0 < --brake23; ) {}
        }
    }();
    for (key18 in expr18) {
        c = 1 + c;
        var bar = expr18[key18], brake25 = 5;
        0;
    }

  case b <<= a:
    var brake28 = 5;
    do {
        var expr29 = [ (c += 1) + (b += a) ];
        for (let key29 of expr29) {
            c = 1 + c;
            var arguments, bar_1 = expr29[key29];
            if ((-3 <= (2 === [ , 0 ].length) ^ NaN) <= ((-0 ^ 2 === [ , 0 ].length) != {} <= "undefined")) {
                for (var brake32 = 5; a++, (a++ + (24..toString() in [ --b + b, a++ + ("function" == typeof f0 && 0 <= --_calls_ && f0(-0)) ]) || 7).toString()[yield_2 && "function" == typeof yield_2.set && 0 <= --_calls_ && yield_2.set(b + 1 - .1 - .1 - .1)], 
                key29 && key29.foo && 0 < --brake32; ) {}
            } else {}
        }
    } while (--b, --a, 0 < --brake28);
}

var brake34 = 5;

do {
    var NaN_1 = (c += 1) + ("function" == typeof f0 && 0 <= --_calls_ && f0(2 === [ , 0 ].length, b++)), b_2 = a++ + (("" | 24..toString()) >>> NaN && b_2 && (b_2[(c += 1) + (c = 1 + c, 
    (+("number" !== {}) || a || 3).toString())] += 0 | 23..toString() >> "bar"));
} while ((({
    static: bar,
    [(c += 1) + (((38..toString() ^ 23..toString()) === (yield_2 && ([ yield_2.in ] = [ 22 / [] ]))) >= (b_2 && ([ b_2[--b + b] ] = [ !1 ])))]: async_2
}) => ({
    [--b + (yield_2 && yield_2[{
        null: [ "function" == typeof f1 && 0 <= --_calls_ && f1((c = 1 + c, c += 1, (23..toString() && "bar") & !0 >>> 23..toString())), b &= a, a ].Infinity,
        value: --b + !0,
        done: --b + ("function" == typeof f1 && 0 <= --_calls_ && f1`${a++ + (bar && bar.null)}${--b + !1}${NaN}$${22 in {
            null: (c = 1 + c, NaN / (c += 1, -0) !== !1)
        }}${a++}`)
    }])]: a++ + {}.Infinity,
    [NaN_1 && "function" == typeof NaN_1.foo && 0 <= --_calls_ && NaN_1.foo(-0)]: --b + b--,
    value: --b + --b
}))({
    undefined: 1,
    [(c += 1) + ({} < -2 && yield_2 && (yield_2.then >>= (23..toString(), -1)), !0)]: -2
}) && 0 < --brake34);

console.log(null, a, b, c, 1 / 0, NaN, void 0);
original result:
null 2202 12268 2250 Infinity NaN undefined

uglified result:
Error: Script execution aborted.
    at run_code_exec (/home/runner/work/UglifyJS/UglifyJS/test/sandbox.js:298:35)
    at Object.exports.run_code (/home/runner/work/UglifyJS/UglifyJS/test/sandbox.js:35:16)
    at run_code (/home/runner/work/UglifyJS/UglifyJS/test/ufuzz/index.js:2084:20)
    at /home/runner/work/UglifyJS/UglifyJS/test/ufuzz/index.js:2484:29
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (/home/runner/work/UglifyJS/UglifyJS/test/ufuzz/index.js:2475:20)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3
// reduced test case (output will differ)

// (beautified)
{
    (({
        [([] = 0)]: async_2
    }) => a)();
}
// output: TypeError: Cannot destructure 'undefined' or 'null'.
// minify: Error: Script execution aborted.
// options: {
//   "mangle": false,
//   "output": {
//     "v8": true
//   },
//   "validate": true
// }
minify(options):
{
  "mangle": false,
  "output": {
    "v8": true
  }
}
@alexlamsl
Copy link
Collaborator Author

@kzc this one's simpler than #5212 − no rest syntax required:

$ node -v
v6.17.1
$ echo '(({[[] = []]: a}) => console.log("PASS"))(0);' | node
PASS
$
$ node -v
v8.17.0
$ echo '(({[[] = []]: a}) => console.log("PASS"))(0);' | node

$
$ node -v
v10.24.1
$ echo '(({[[] = []]: a}) => console.log("PASS"))(0);' | node
PASS
$

Seems to be a parser bug, since a pair of braces would mask it:

$ node -v
v8.17.0
$ echo '{ (({[[] = []]: a}) => console.log("PASS"))(0); }' | node
PASS
$ echo '(({[[] = []]: a}) => { console.log("PASS") })(0);' | node
PASS

Current mystery for me: this bug seems to be popping up more frequently on ufuzz all of a sudden... 🤔

@kzc
Copy link
Contributor

kzc commented Dec 10, 2021

Current mystery for me: this bug seems to be popping up more frequently on ufuzz all of a sudden... 🤔

prng not so random?

@alexlamsl
Copy link
Collaborator Author

prng not so random?

I sincerely hope not − it's not like we casually spam Math.random():

function rng(max) {
var r = randomBytes(2).readUInt16LE(0) / 65536;
return Math.floor(max * r);
}

and if not, then I hope nobody is using GitHub Actions to generate key pairs❗😅

@kzc
Copy link
Contributor

kzc commented Dec 10, 2021

This shows that prng distribution looks pretty uniform - on my machine at least...

--- a/test/ufuzz/index.js
+++ b/test/ufuzz/index.js
@@ -11,2 +11,6 @@ var UglifyJS = require("../..");
 var randomBytes = require("crypto").randomBytes;
+
+for (var i = 0; i < 1e6; i++) console.log(rng(19));
+process.exit(0);
+
 var sandbox = require("../sandbox");
$ node test/ufuzz/index.js | sort -n | uniq -c
52916 0
52409 1
52411 2
52537 3
52732 4
52501 5
52431 6
52609 7
52410 8
52623 9
52662 10
52880 11
53251 12
52722 13
52598 14
52774 15
52373 16
52486 17
52675 18
$ node test/ufuzz/index.js | sort -n | uniq -c
52531 0
52789 1
52229 2
52631 3
52975 4
52481 5
52342 6
53106 7
52137 8
52355 9
52643 10
52736 11
52948 12
52746 13
52678 14
52669 15
52966 16
52565 17
52473 18

@alexlamsl
Copy link
Collaborator Author

alexlamsl commented Dec 10, 2021

Good to know − although if we have a problem with the initial seed, or if there is non-uniformity in n-grams distribution, then we will still experience uneven/clustered test cases while displaying perfect first-order uniformity.

@kzc
Copy link
Contributor

kzc commented Dec 10, 2021

Yeah, I ran it twice to demonstrate that the initial seed was different - which it obviously would have to be to generate unique test cases at all. No measure of the quality of the entropy though.

I assume if that program were to be run on the github cluster it'd also produce a uniform distribution. But it might be worth verifying.

@alexlamsl
Copy link
Collaborator Author

Yeah, I ran it twice to demonstrate that the initial seed was different

Ah of course − sorry for the thinko 😅

I assume if that program were to be run on the github cluster it'd also produce a uniform distribution. But it might be worth verifying.

What I've observed so far is that the same type of false positives tend to happen in clusters, temporally speaking. The test requires to show definitive results is probably rather prohibitive in size − and even assuming such deficiencies, ufuzz would still do its job albeit at a discounted rate.

@kzc
Copy link
Contributor

kzc commented Dec 10, 2021

Beyond the prng algorithm, I don't think independent node processes on the same machines or different machines share any state. Conceivably a new node patch release could be used by github CI that introduced a bug. Then there's always this possibility:

https://www.absolutdata.com/learn-analytics-whitepapers-webinars/clustering-illusion-clusters-lie-in-the-eye-of-the-beholder/

@alexlamsl
Copy link
Collaborator Author

But if you were to flip that coin 1,000 times, the odds of getting ten or more heads in a row are a surprising 62 percent.

OT: I've got curious about that, so I tried to derive the formula for it − but I've got 38.5% instead:

<!doctype html>
<html>
<head>
    <title>Probability of r heads or more in a row for n flips</title>
</head>
<body>
    r = <input id=r type=text value=10 />
    <br />
    n = <input id=n type=text value=1000 />
    <br />
    P(n, r) = <input id=P type=text size=30 />
    <button onclick="document.all.P.value=calc(1*document.all.n.value,1*document.all.r.value)">Calculate</button>
    <script>
        var cache = [];
        function calc(n, r) {
            if (n < r) return 0;
            var ans = cache[r];
            if (!ans) ans = cache[r] = [];
            if (!(n in ans)) {
                var p = 2 + n - r;
                for (var q = 0, l = 2 * r; l < n; l++) {
                    q += calc(l - r, r);
                }
                ans[n] = (p - q) * Math.pow(2, -r - 1);
            }
            return ans[n];
        }
    </script>
    <br />
    Q(n, r) = <input id=Q type=text size=30 />
    <button onclick="simulate(document.all.Q,1*document.all.n.value,1*document.all.r.value)">Simulate</button>
    <script>
        var tid;
        function simulate(el, n, r) {
            clearInterval(tid);

            var count = 0, hit = 0;
            var rounds = 10000;
            // calibrate update interval
            var start = Date.now();
            test(rounds);
            rounds = Math.ceil(rounds * 500 / (Date.now() - start));
            tid = setInterval(function () {
                test(rounds);
                el.value = hit / count;
            }, 1);

            function test(rounds) {
                while (--rounds >= 0) {
                    count++;
                    for (var i = 0, j = 0; i < n; i++) {
                        if (Math.random() < 0.5) {
                            j = 0;
                        } else if (++j == r) {
                            hit++;
                            break;
                        }
                    }
                }
            }
        }
    </script>
</body>
</html>

@kzc
Copy link
Contributor

kzc commented Dec 11, 2021

But if you were to flip that coin 1,000 times, the odds of getting ten or more heads in a row are a surprising 62 percent.

OT: I've got curious about that, so I tried to derive the formula for it − but I've got 38.5% instead:

My independently written program agrees with your result:

$ cat odds.js 
function trial(flips) {
    var results = "";
    for (var i = 0; i < flips; ++i) {
        results += Math.random() < 0.5 ? "H" : "T";
    }
    return results.includes("HHHHHHHHHH");
}
var flips_per_trial = +process.argv[2] || 1000;
var trials = 1e6;
console.log("flips_per_trial:", flips_per_trial);
console.log("trials:", trials);
var trials_with_ten_heads_in_a_row = 0;
for (var i = 0; i < trials; ++i) {
    if (trial(flips_per_trial)) ++trials_with_ten_heads_in_a_row;
}
console.log("trials_with_ten_heads_in_a_row:", trials_with_ten_heads_in_a_row);
console.log("percent:", trials_with_ten_heads_in_a_row / trials * 100);
$ node odds.js
flips_per_trial: 1000
trials: 1000000
trials_with_ten_heads_in_a_row: 385244
percent: 38.5244
$ node odds.js
flips_per_trial: 1000
trials: 1000000
trials_with_ten_heads_in_a_row: 385903
percent: 38.5903

To exceed 62% you need to flip 2000 coins per trial:

$ node odds.js 2000
flips_per_trial: 2000
trials: 1000000
trials_with_ten_heads_in_a_row: 623130
percent: 62.312999999999995

@kzc
Copy link
Contributor

kzc commented Dec 11, 2021

Although the assertion in the linked blog was likely wrong or the problem was misstated, I think the point that clustering is not uncommon with random data is valid.

@alexlamsl
Copy link
Collaborator Author

So the real reason for these false positives popping up is because prior to d2e7c4a ufuzz will just crash instead thus not being reported at all:

UglifyJS/test/ufuzz/index.js:2438
        return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter";
                  ^

TypeError: Cannot read property 'name' of undefined
    at bug_async_arrow_rest (UglifyJS/test/ufuzz/index.js:2438:19)

@kzc
Copy link
Contributor

kzc commented Dec 11, 2021

It makes perfect sense in hindsight. Good you got to the bottom of that.

Do you plan to change ufuzz to not generate a non-compliant rest parameter?

@alexlamsl
Copy link
Collaborator Author

alexlamsl commented Dec 11, 2021

Thanks to you for discovering those test/compress failures for specific v8 versions − without patching that we would not have uncovered this 😉

Do you plan to change ufuzz to not generate a non-compliant rest parameter?

Not really − my plan is to teach ufuzz to recognise these v8 crashes as SEP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants