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 #3689

Closed
alexlamsl opened this issue Jan 27, 2020 · 11 comments · Fixed by #3692
Closed

ufuzz failure #3689

alexlamsl opened this issue Jan 27, 2020 · 11 comments · Fixed by #3692
Labels

Comments

@alexlamsl
Copy link
Collaborator

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

function f0(a_1) {
    return a_1 += (c = c + 1) + (a++ + [ typeof f2 == "function" && --_calls_ >= 0 && f2(void function() {
        c = 1 + c, (("undefined" ^ "c") >> ([ , 0 ].length === 2) - 24..toString()) % ((Infinity & undefined) >>> (4 ^ "a"));
    }(), --b + a++, delete b), , (c = c + 1) + (a_1 && a_1[/[abc4]/.test(([ (c = 1 + c, 
    ((a_1 && (a_1[c = 1 + c, "b" >> 24..toString() >>> "function" + "c" != (a_1 && (a_1.c = 0 / -1 - (a_1 && (a_1[c = 1 + c, 
    (-2 <= "function" || 0 + false) << (1 == 2) % (38..toString() == ([ , 0 ].length === 2))] >>>= "b" & []))))] += 0 >>> 23..toString())) & (3 ^ 3)) << ((5 | 25) >> "undefined" + 5)), , (c = 1 + c, 
    (c = c + 1, "foo" >> "object") != ((c = c + 1, "foo") ^ (1, 5))), (c = 1 + c, (38..toString() ^ 2) - (-4 !== -5) != (NaN === "number") < null + 24..toString()), (c = 1 + c, 
    ("object" ^ -1) > 3 - 22 < (!2 !== (a_1 = 5 >>> {}))) ][c = 1 + c, -1 & -1 && (23..toString(), 
    Infinity), (a_1 <<= "a" != false) << (undefined < this)] || b || 5).toString())] || a || 3).toString(), --b + (--b + delete b || a || 3).toString(), a_1 && a_1[b = a] ].NaN || a || 3).toString();
}

var c = f0([]);

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

i = function(e) {
    return e + ((i += 1) + "") + (t++ + [ "function" == typeof f2 && 0 <= --o && f2(void (i = 1 + i), --n + t++, delete n), , (i += 1) + "" + (e && e[/[abc4]/.test("" + ([ (i = 1 + i, 
    (0 & (e && (e[i = 1 + i, 0 != (e && (e.c = -0 - (e && (e[i = 1 + i, 0] >>>= 0))))] += 0))) << 29), , (i = 1 + i, 
    !0), !0, !0 < (!1 !== (e = 5)) ][i = 1 + (1 + (1 + ((i += 1) + 1))), (e <<= !0) << (void 0 < this)] || n || 5))] || t || 3), --n + "" + (--n + delete n || t || 3), e && e[n = t] ].NaN || t || 3);
}([]), console.log(null, t, n, i, 1 / 0, NaN, void 0);
original result:
null 101 101 '01101' Infinity NaN undefined

uglified result:
null 101 101 '1101' Infinity NaN undefined

minify(options):
{
  "compress": {
    "passes": 1000000,
    "unsafe": true
  },
  "toplevel": true
}
@alexlamsl
Copy link
Collaborator Author

@kzc this one's a little tricky.

$ cat test.js
console.log(function(a) {
    return a + (a[0] = 0).toString();
}([]));

$ cat test.js | node
00

$ uglifyjs test.js -c unsafe | node
0

$ uglifyjs test.js -c unsafe
console.log(function(a) {
    return a + "" + (a[0] = 0);
}([]));

@kzc
Copy link
Contributor

kzc commented Jan 27, 2020

Good one.

Given the dynamic nature of the language, I suspect that a bug-free optimizing JS compiler is not possible.

@alexlamsl
Copy link
Collaborator Author

A bit worse than that - most browser (except Chrome) used to be capable of handling large memory usage (say 64GB), but all that has changed in the last couple of years.

Firefox nowadays blows up around the 20GB mark, and for some bizarre reason Microsoft decided to "update" IE11 such that it can't only use 2GB before going OOM. (Safari won't even load WebWorker properly since at least a year ago so let's not mention that.)

@kzc
Copy link
Contributor

kzc commented Jan 27, 2020

I've been amazed by the speed of these JS JIT engines, but it's only possible with some compromises as you've discovered. You can only imagine the bug attack surface of these engines given their incredible complexity.

@kzc
Copy link
Contributor

kzc commented Jan 27, 2020

I'm also curious what JS applications you're designing that need 64GB in a browser. The language was invented to do simple form field validation, after all. :-)

@alexlamsl
Copy link
Collaborator Author

Just running data analytics with distributed storage, nothing fancy 😉

Thought I would (ab)use web technologies as much as I could, but the recent push of feature creep and security theatre is really making me wonder if I should migrate away from this platform.

@alexlamsl
Copy link
Collaborator Author

Still remember back in the days when Internet Explorer first introduced CSS crop and transparency filters − making image kernels (e.g. sharpen, motion blur) to work inside the browser was hours of fun. 🤣

@alexlamsl alexlamsl added the bug label Jan 27, 2020
alexlamsl added a commit to alexlamsl/UglifyJS that referenced this issue Jan 27, 2020
- migrate de-facto compression to `conditionals` & `strings`

fixes mishoo#3689
alexlamsl added a commit to alexlamsl/UglifyJS that referenced this issue Jan 27, 2020
- migrate de-facto compression to `conditionals` & `strings`

fixes mishoo#3689
alexlamsl added a commit that referenced this issue Jan 27, 2020
- migrate de-facto compression to `conditionals` & `strings`

fixes #3689
@kzc
Copy link
Contributor

kzc commented Jan 28, 2020

the recent push of feature creep and security theatre is really making me wonder if I should migrate away from this platform

That's been my thought as well. The back end alternatives all have their own issues and baggage though.

making image kernels (e.g. sharpen, motion blur) to work inside the browser was hours of fun. 🤣

I didn't even know that was a thing! It's getting harder and harder to be a programming generalist these days - so much technology to learn. You're basically forced to to pick a silo and run with it.

@alexlamsl
Copy link
Collaborator Author

After #3710:

$ uglifyjs test.js --toplevel -mc passes=1000000,unsafe --reduce-test
// reduce test pass 1, iteration 0: 1271 bytes
// reduce test pass 1, iteration 25: 918 bytes
// reduce test pass 1, iteration 50: 726 bytes
// reduce test pass 1, iteration 75: 373 bytes
// reduce test pass 1, iteration 100: 260 bytes
// reduce test pass 1, iteration 125: 131 bytes
// reduce test pass 1: 131 bytes
// reduce test pass 2: 126 bytes
// reduce test pass 3: 126 bytes
var a = 0, b = 0;

function f0(a_1) {
    return a_1 += (a_1[0] >>>= 0).toString();
}

var c = f0([]);

console.log(null, a, b, c, Infinity, NaN, undefined);
// output: null 0 0 00 Infinity NaN undefined
// minify: null 0 0 0 Infinity NaN undefined
// options: {"compress":{"passes":1000000,"unsafe":true},"mangle":true,"toplevel":true}

@kzc
Copy link
Contributor

kzc commented Feb 7, 2020

Not bad at all. Just curious what was generated before #3710.

@kzc
Copy link
Contributor

kzc commented Feb 7, 2020

The reduced result looks to be the same when run against #3705 for the test case above.

However, I've seen a slight improvement in other test cases - generally as result of the AST_BlockStatement splice.

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

Successfully merging a pull request may close this issue.

2 participants