Bug report
An optimization in v3.4.9 seems to be moving an array assignment to before the array is created.
Bisected the problem to 2bdaca10ae05136843d8e99da50925091a593373 (#3243).
Uglify version (uglifyjs -V)
uglify-js 3.4.9
JavaScript input
Input (simplified from some code in Turbulenz that trigger this):
function v3Build(r, dst) {
var res;
var length = arguments.length;
if (length >= 3) {
if (length > 3) {
res = arguments[3];
if (res === undefined) {
res = new Float32Array(3);
}
} else {
res = new Float32Array(3);
}
res[0] = arguments[0];
res[1] = arguments[1];
res[2] = arguments[2];
} else {
res = dst;
if (res === undefined) {
res = new Float32Array(3);
}
res[0] = r[0];
res[1] = r[1];
res[2] = r[2];
}
return res;
}
console.log(v3Build([1,2,3]));
Expected output: Float32Array [ 1, 2, 3 ]
The uglifyjs CLI command executed or minify() options used.
uglifyjs --compress
JavaScript output or error produced.
Generated code (with --beautify for clarity):
function v3Build(r, dst) {
var res, length = arguments.length;
return res[2] = 3 <= length ? (3 < length ? void 0 === (res = arguments[3]) && (res = new Float32Array(3)) : res = new Float32Array(3),
res[0] = r, res[1] = dst, arguments[2]) : (void 0 === (res = dst) && (res = new Float32Array(3)),
res[0] = r[0], res[1] = r[1], r[2]), res;
}
console.log(v3Build([ 1, 2, 3 ]));
Running output:
out.js:3
return res[2] = 3 <= length ? (3 < length ? void 0 === (res = arguments[3]) && (res = n...
^
TypeError: Cannot set property '2' of undefined
at v3Build (out.js:3:19)
at Object.<anonymous> (out.js:8:13)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Confirmed working in 3.4.8 and broken in 3.4.9 for me too, @alexlamsl it looks like there is a major bug in 3.4.9.
Input:
var modelClassName,
routeName = '',
parentName = '',
routeEnd = '';
if ( parentName === 'x' ) {
parentName = '';
}
if ( 'me' === routeEnd ) {
routeName = 'me';
}
if ( '' !== parentName && parentName !== routeName ) {
modelClassName = parentName + routeName;
modelClassName = mapping.models[ modelClassName ] || modelClassName;
loadingObjects.models[ modelClassName ] = thing();
} else {
modelClassName = routeName;
modelClassName = mapping.models[ modelClassName ] || modelClassName;
loadingObjects.models[ modelClassName ] = thing();
}
Output with -c -m -b options (note that loadingObjects.models[modelClassName] is executed before modelClassName is assigned):
var modelClassName, routeName = "", parentName = "", routeEnd = "";
"x" === parentName && (parentName = ""), "me" === routeEnd && (routeName = "me"),
loadingObjects.models[modelClassName] = (modelClassName = (modelClassName = "" !== parentName && parentName !== routeName ? parentName + routeName : routeName,
mapping.models[modelClassName] || modelClassName), thing());
Releasing a new version and then disappearing is bad form. Please follow up with your community after the release.
If you don't have time to do that, better not to do the release in the first place.
Someone at least, remove v3.4.9 from here and npm. It is a dangerous version
Very surprised to see that this still has not been rolled back. We unfortunately did not catch the issue until it entered production code (it did not manifest itself as a code exception, but instead as data mutation), by which point it had triggered a major incident for us.
Most helpful comment
Someone at least, remove v3.4.9 from here and npm. It is a dangerous version