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

Invalid left-hand side in for-in #1944

yuanzm opened this Issue Jul 11, 2018 · 3 comments


None yet
4 participants

yuanzm commented Jul 11, 2018

Steps to reproduce

// some code from TweenMax.min.js
var code = `
function a() {
				var e, i, n, a, o = this._tween,
					l = o.vars.roundProps,
					h = {},
					_ = o._propLookup.roundProps;
				if ("object" != (void 0 === l ? "undefined" : t(l)) || l.push) for ("string" == typeof l && (l = l.split(",")), n = l.length; --n > -1;) h[l[n]] = Math.round;
				else for (a in l) h[a] = s(l[a]);
				for (a in h) for (e = o._firstPT; e;) i = e._next, ? e.t._mod(h) : e.n === a && (2 === e.f && e.t ? r(e.t._firstPT, h[a]) : (this._add(e.t, a, e.s, e.c, h[a]), i && (i._prev = e._prev), e._prev ? e._prev._next = i : o._firstPT === e && (o._firstPT = i), e._next = e._prev = null, o._propLookup[a] = _)), e = i;
				return !1

Expected output

AST tree

Actual output

Error: Line 8: Invalid left-hand side in for-in
at ErrorHandler.constructError (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:5004:22)
at ErrorHandler.createError (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:5020:27)
at ErrorHandler.tolerateError (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:5030:27)
at Parser.tolerateError (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:1951:28)
at Parser.parseForStatement (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:3802:31)
at Parser.parseStatement (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:4127:43)
at Parser.parseIfClause (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:3647:22)
at Parser.parseIfStatement (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:3665:35)
at Parser.parseStatement (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:4133:43)
at Parser.parseStatementListItem (/Users/yuanzimin/tmp/minigame-code-check/node_modules/esprima/dist/esprima.js:3378:39)

If I replace the code in line 8

else for (a in l) h[a] = s(l[a]);


else { for (a in l) h[a] = s(l[a]); }


else for (var a in l) h[a] = s(l[a]);

It works!!
I tried to read the source code,but it was too complicated.... help...


This comment has been minimized.


ariya commented Jul 16, 2018

I can reproduce it. Looks like a terrible bug, I have a look. Thanks for the detailed report!

@ariya ariya added the defect label Jul 16, 2018


This comment has been minimized.

lmy375 commented Aug 15, 2018

I met same issue recently. Here is a simpler PoC script.

if (1)
    for (a of '1'){} // after parsing '1', context.isAssignmentTarget is set false.
    for (v in v){}  // while parseing this statement, context.isAssignmentTarget is set still false.

With some debugging I think the root cause is probably that isAssignmentTarget flag is not reset each time before starting parsing a new statement.

    parseStatement(): Node.Statement {
+       this.context.isAssignmentTarget = true;
        let statement: Node.Statement;
        switch (this.lookahead.type) {
            case Token.BooleanLiteral:

After patching this, esprima works on PoC script! But I'm not sure if this will lead to other side effects.


This comment has been minimized.

betalb commented Oct 31, 2018

Putting brackets around else block, also hides issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment