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

Undefined object reference in v3.4.9 (works fine in 3.4.8) #3257

Closed
Akurn opened this issue Sep 14, 2018 · 3 comments · Fixed by #3329
Closed

Undefined object reference in v3.4.9 (works fine in 3.4.8) #3257

Akurn opened this issue Sep 14, 2018 · 3 comments · Fixed by #3329

Comments

@Akurn
Copy link

Akurn commented Sep 14, 2018

Bug report or feature request?
Bug report

Uglify version (uglifyjs -V)
uglify-js 3.4.9

JavaScript input

function Main(){}
Main.prototype.func1 = function () {
    return {};
}
Main.prototype.brokenFunc = function (type) {
    var n;
    if (type === '1') {
        n = this.func1();
        n.prop = {};
        n.prop.obj = {};
    } else {
        if (type === '2') {
            n = this.func1();
        } else {
            n = this.func1();
        }
        n.prop = {};
        n.prop.obj = {};
    }
    return n;
};

The uglifyjs CLI command executed or minify() options used.

uglifyjs --compress --mangle -- main.js > main.min.js

(But does the same thing with just --compress

JavaScript output or error produced.

// result has been spaced out
function Main() {}
Main.prototype.func1 = function() {
    return {}
}, Main.prototype.brokenFunc = function(n) {
    var o;
    return o.prop.obj = ((o = this.func1()).prop = {}, {}), o
};

If you execute that with:

var a = new Main();
a.brokenFunc();

it gets an error:

Uncaught TypeError: Cannot read property 'prop' of undefined

From this line return o.prop.obj ... since o.prop hasn't been defined yet.

UglifyJS 3.4.8 compiles this fine

function Main() {}
Main.prototype.func1 = function() {
    return {}
}, Main.prototype.brokenFunc = function(n) {
    var o;
    return (o = this.func1()).prop = {}, o.prop.obj = {}, o
};
@Akurn
Copy link
Author

Akurn commented Sep 14, 2018

Actually better test case (since the original one is a bit arbitrary repeating the same methods).

function Main(){}
Main.prototype.func1 = function () { return {}; }
Main.prototype.func2 = function () { return {}; }
Main.prototype.func3 = function () { return {}; }
Main.prototype.brokenFunc = function (type) {
    var n;
    if (type === '1') {
        n = this.func1();
        n.prop = {};
        n.prop.obj = {};
    } else {
        if (type === '2') {
            n = this.func2();
        } else {
            n = this.func3();
        }
        n.prop = {};
        n.prop.obj = {};
    }
    return n;
};

Produces this output:

function Main() {}
Main.prototype.func1 = function() {
    return {}
}, Main.prototype.func2 = function() {
    return {}
}, Main.prototype.func3 = function() {
    return {}
}, Main.prototype.brokenFunc = function(type) {
    var n;
    return n.prop.obj = ("1" === type ? (n = this.func1()).prop = {} : (n = "2" === type ? this.func2() : this.func3()).prop = {}, {}), n
};

Same error.

@jordanmarshallEL
Copy link

I experienced a very similar problem with the following code. It worked in 3.4.8, but broke in 3.4.9.

Javascript Input

function drawX(_arr1 , _arr2 , _ctx , _ht , _color , _bool)
	{
		var tempArr = _arr2.slice(0);
		var tempArr1 = _arr1.slice(0);

		var tempPt1 = {x : tempArr[2].x , y : tempArr[2].y - _ht};
		var tempPt2 = {x : tempArr[1].x , y : tempArr[1].y - _ht};
        var tempPt3 , tempPt4;
        
		if(_bool)
		{
			tempPt3 = {x : tempArr1[1].x , y : tempArr1[1].y};
			tempPt4 = {x : tempArr1[2].x + globalResizeCalc(0.5) , y : tempArr1[2].y - globalResizeCalc(3)};		
		}
		else
		{
			tempPt3 = {x : tempArr1[1].x , y : tempArr1[1].y};
			tempPt4 = {x : tempArr1[2].x , y : tempArr1[2].y};
		}
			
		drawY(tempPt3 , tempPt4 , tempPt1 , tempPt2 , _ctx , _color);
	}

Uglify Options

Default options, with drop_console set to true.

Javascript Output

    function ie(e, i, a, t, l, o) {
        var s, n = i.slice(0), g = e.slice(0), b = {
            x: n[2].x,
            y: n[2].y - t
        }, c = {
            x: n[1].x,
            y: n[1].y - t
        };
        ae(s, o ? (s = {
            x: g[1].x,
            y: g[1].y
        },
        {
            x: g[2].x + globalResizeCalc(.5),
            y: g[2].y - globalResizeCalc(3)
        }) : (s = {
            x: g[1].x,
            y: g[1].y
        },
        {
            x: g[2].x,
            y: g[2].y
        }), b, c, a, l)
    }

This is trivially broken - notice that s is not assigned a value until you get to the function call itself (ae).

@nylen
Copy link

nylen commented Oct 9, 2018

Lots of reports about this :(

See also #3269 (comment)

alexlamsl added a commit to alexlamsl/UglifyJS that referenced this issue Mar 12, 2019
alexlamsl added a commit that referenced this issue Mar 12, 2019
fixes #3245
fixes #3257
fixes #3260
fixes #3269
fixes #3271
fixes #3278
fixes #3309
fixes #3319
fixes #3321
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.

3 participants