improve sandbox fidelity (#3415)
This commit is contained in:
@@ -451,6 +451,7 @@ merge(Compressor.prototype, {
|
|||||||
if (tw.safe_ids[def.id]) {
|
if (tw.safe_ids[def.id]) {
|
||||||
if (def.fixed == null) {
|
if (def.fixed == null) {
|
||||||
if (is_arguments(def)) return false;
|
if (is_arguments(def)) return false;
|
||||||
|
if (def.global && def.name == "arguments") return false;
|
||||||
def.fixed = make_node(AST_Undefined, def.orig);
|
def.fixed = make_node(AST_Undefined, def.orig);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -894,9 +895,13 @@ merge(Compressor.prototype, {
|
|||||||
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
||||||
});
|
});
|
||||||
|
|
||||||
function is_lhs_read_only(lhs) {
|
function is_lhs_read_only(lhs, compressor) {
|
||||||
if (lhs instanceof AST_This) return true;
|
if (lhs instanceof AST_This) return true;
|
||||||
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
if (lhs instanceof AST_SymbolRef) {
|
||||||
|
var def = lhs.definition();
|
||||||
|
return def.orig[0] instanceof AST_SymbolLambda
|
||||||
|
|| compressor.exposed(def) && identifier_atom[def.name];
|
||||||
|
}
|
||||||
if (lhs instanceof AST_PropAccess) {
|
if (lhs instanceof AST_PropAccess) {
|
||||||
lhs = lhs.expression;
|
lhs = lhs.expression;
|
||||||
if (lhs instanceof AST_SymbolRef) {
|
if (lhs instanceof AST_SymbolRef) {
|
||||||
@@ -905,7 +910,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (!lhs) return true;
|
if (!lhs) return true;
|
||||||
if (lhs.is_constant()) return true;
|
if (lhs.is_constant()) return true;
|
||||||
return is_lhs_read_only(lhs);
|
return is_lhs_read_only(lhs, compressor);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1220,7 +1225,7 @@ merge(Compressor.prototype, {
|
|||||||
var stop_if_hit = null;
|
var stop_if_hit = null;
|
||||||
var lhs = get_lhs(candidate);
|
var lhs = get_lhs(candidate);
|
||||||
var side_effects = lhs && lhs.has_side_effects(compressor);
|
var side_effects = lhs && lhs.has_side_effects(compressor);
|
||||||
var scan_lhs = lhs && !side_effects && !is_lhs_read_only(lhs);
|
var scan_lhs = lhs && !side_effects && !is_lhs_read_only(lhs, compressor);
|
||||||
var scan_rhs = foldable(get_rhs(candidate));
|
var scan_rhs = foldable(get_rhs(candidate));
|
||||||
if (!scan_lhs && !scan_rhs) continue;
|
if (!scan_lhs && !scan_rhs) continue;
|
||||||
// Locate symbols which may execute code outside of scanning range
|
// Locate symbols which may execute code outside of scanning range
|
||||||
|
|||||||
100
test/compress.js
100
test/compress.js
@@ -1,35 +1,47 @@
|
|||||||
#! /usr/bin/env node
|
|
||||||
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var child_process = require("child_process");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var sandbox = require("./sandbox");
|
var sandbox = require("./sandbox");
|
||||||
var semver = require("semver");
|
var semver = require("semver");
|
||||||
var U = require("./node");
|
var U = require("./node");
|
||||||
|
|
||||||
var failures = 0;
|
var file = process.argv[2];
|
||||||
var failed_files = Object.create(null);
|
|
||||||
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
|
||||||
var dir = path.resolve(path.dirname(module.filename), "compress");
|
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||||
fs.readdirSync(dir).filter(function(name) {
|
if (file) {
|
||||||
return /\.js$/i.test(name);
|
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||||
}).forEach(function(file) {
|
|
||||||
log("--- {file}", { file: file });
|
log("--- {file}", { file: file });
|
||||||
var tests = parse_test(path.resolve(dir, file));
|
var tests = parse_test(path.resolve(dir, file));
|
||||||
for (var i in tests) if (!test_case(tests[i])) {
|
process.exit(Object.keys(tests).filter(function(name) {
|
||||||
failures++;
|
return !test_case(tests[name]);
|
||||||
failed_files[file] = 1;
|
}).length);
|
||||||
}
|
} else {
|
||||||
});
|
var files = fs.readdirSync(dir).filter(function(name) {
|
||||||
if (failures) {
|
return /\.js$/i.test(name);
|
||||||
console.error();
|
});
|
||||||
console.error("!!! Failed " + failures + " test case(s).");
|
var failures = 0;
|
||||||
console.error("!!! " + Object.keys(failed_files).join(", "));
|
var failed_files = Object.create(null);
|
||||||
process.exit(1);
|
(function next() {
|
||||||
|
var file = files.shift();
|
||||||
|
if (file) {
|
||||||
|
child_process.spawn(process.argv[0], [ process.argv[1], file ], {
|
||||||
|
stdio: [ "ignore", 1, 2 ]
|
||||||
|
}).on("exit", function(code) {
|
||||||
|
if (code) {
|
||||||
|
failures += code;
|
||||||
|
failed_files[file] = code;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
} else if (failures) {
|
||||||
|
console.error();
|
||||||
|
console.error("!!! Failed " + failures + " test case(s).");
|
||||||
|
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----[ utils ]----- */
|
|
||||||
|
|
||||||
function evaluate(code) {
|
function evaluate(code) {
|
||||||
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
|
if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });
|
||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
@@ -160,7 +172,7 @@ function parse_test(file) {
|
|||||||
|
|
||||||
// Try to reminify original input with standard options
|
// Try to reminify original input with standard options
|
||||||
// to see if it matches expect_stdout.
|
// to see if it matches expect_stdout.
|
||||||
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||||
for (var i = 0; i < minify_options.length; i++) {
|
for (var i = 0; i < minify_options.length; i++) {
|
||||||
var options = JSON.parse(minify_options[i]);
|
var options = JSON.parse(minify_options[i]);
|
||||||
if (options.compress) [
|
if (options.compress) [
|
||||||
@@ -191,11 +203,12 @@ function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var stdout = run_code(result.code);
|
var expected = stdout[options.toplevel ? 1 : 0];
|
||||||
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
var actual = run_code(result.code, options.toplevel);
|
||||||
stdout = expect_stdout;
|
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||||
|
actual = expected;
|
||||||
}
|
}
|
||||||
if (!sandbox.same_stdout(expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(expected, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! failed running reminified input",
|
"!!! failed running reminified input",
|
||||||
"---INPUT---",
|
"---INPUT---",
|
||||||
@@ -214,10 +227,10 @@ function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
|||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
options: options_formatted,
|
options: options_formatted,
|
||||||
output: result.code,
|
output: result.code,
|
||||||
expected_type: typeof expect_stdout == "string" ? "STDOUT" : "ERROR",
|
expected_type: typeof expected == "string" ? "STDOUT" : "ERROR",
|
||||||
expected: expect_stdout,
|
expected: expected,
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
actual: stdout,
|
actual: actual,
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -226,8 +239,8 @@ function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_code(code) {
|
function run_code(code, toplevel) {
|
||||||
var result = sandbox.run_code(code, true);
|
var result = sandbox.run_code(code, toplevel);
|
||||||
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,13 +372,14 @@ function test_case(test) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test.expect_stdout
|
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
var stdout = [ run_code(input_code), run_code(input_code, true) ];
|
||||||
var stdout = run_code(input_code);
|
var toplevel = test.options.toplevel;
|
||||||
|
var actual = stdout[toplevel ? 1 : 0];
|
||||||
if (test.expect_stdout === true) {
|
if (test.expect_stdout === true) {
|
||||||
test.expect_stdout = stdout;
|
test.expect_stdout = actual;
|
||||||
}
|
}
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! Invalid input or expected stdout",
|
"!!! Invalid input or expected stdout",
|
||||||
"---INPUT---",
|
"---INPUT---",
|
||||||
@@ -380,13 +394,13 @@ function test_case(test) {
|
|||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
expected: test.expect_stdout,
|
expected: test.expect_stdout,
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
actual: stdout,
|
actual: actual,
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stdout = run_code(output);
|
actual = run_code(output, toplevel);
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! failed",
|
"!!! failed",
|
||||||
"---INPUT---",
|
"---INPUT---",
|
||||||
@@ -401,12 +415,12 @@ function test_case(test) {
|
|||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
expected: test.expect_stdout,
|
expected: test.expect_stdout,
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
actual_type: typeof actual == "string" ? "STDOUT" : "ERROR",
|
||||||
actual: stdout,
|
actual: actual,
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!reminify(test.options, input_code, input_formatted, test.expect_stdout)) {
|
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6178,3 +6178,22 @@ assign_undeclared: {
|
|||||||
"object",
|
"object",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Infinity_assignment: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Infinity;
|
||||||
|
Infinity = 42;
|
||||||
|
console.log(Infinity);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var Infinity;
|
||||||
|
Infinity = 42;
|
||||||
|
console.log(Infinity);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ mangle_catch_redef_3: {
|
|||||||
console.log(o);
|
console.log(o);
|
||||||
}
|
}
|
||||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_catch_redef_3_toplevel: {
|
mangle_catch_redef_3_toplevel: {
|
||||||
@@ -389,10 +389,10 @@ mangle_catch_redef_3_toplevel: {
|
|||||||
console.log(o);
|
console.log(o);
|
||||||
}
|
}
|
||||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_catch_redef_ie8_3: {
|
mangle_catch_redef_3_ie8: {
|
||||||
mangle = {
|
mangle = {
|
||||||
ie8: true,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
@@ -412,7 +412,7 @@ mangle_catch_redef_ie8_3: {
|
|||||||
console.log(o);
|
console.log(o);
|
||||||
}
|
}
|
||||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_catch_redef_3_ie8_toplevel: {
|
mangle_catch_redef_3_ie8_toplevel: {
|
||||||
@@ -435,5 +435,5 @@ mangle_catch_redef_3_ie8_toplevel: {
|
|||||||
console.log(o);
|
console.log(o);
|
||||||
}
|
}
|
||||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,3 +12,57 @@ console_log: {
|
|||||||
"% %s",
|
"% %s",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeof_arguments: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var arguments;
|
||||||
|
console.log((typeof arguments).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var arguments;
|
||||||
|
console.log((typeof arguments).length);
|
||||||
|
}
|
||||||
|
expect_stdout: "6"
|
||||||
|
}
|
||||||
|
|
||||||
|
typeof_arguments_assigned: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var arguments = void 0;
|
||||||
|
console.log((typeof arguments).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("undefined".length);
|
||||||
|
}
|
||||||
|
expect_stdout: "9"
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_Infinity_NaN_undefined: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Infinity = "foo";
|
||||||
|
var NaN = 42;
|
||||||
|
var undefined = null;
|
||||||
|
console.log(Infinity, NaN, undefined);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo", 42, null);
|
||||||
|
}
|
||||||
|
expect_stdout: "foo 42 null"
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,32 +52,19 @@ function createContext() {
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
var context;
|
exports.run_code = function(code, toplevel) {
|
||||||
exports.run_code = function(code, reuse) {
|
|
||||||
var stdout = "";
|
var stdout = "";
|
||||||
var original_write = process.stdout.write;
|
var original_write = process.stdout.write;
|
||||||
process.stdout.write = function(chunk) {
|
process.stdout.write = function(chunk) {
|
||||||
stdout += chunk;
|
stdout += chunk;
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
if (!reuse || !context) context = createContext();
|
vm.runInContext(toplevel ? "(function(){" + code + "})()" : code, createContext(), { timeout: 5000 });
|
||||||
vm.runInContext([
|
|
||||||
"!function() {",
|
|
||||||
code,
|
|
||||||
"}();",
|
|
||||||
].join("\n"), context, { timeout: 5000 });
|
|
||||||
return stdout;
|
return stdout;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
return ex;
|
return ex;
|
||||||
} finally {
|
} finally {
|
||||||
process.stdout.write = original_write;
|
process.stdout.write = original_write;
|
||||||
if (!reuse || code.indexOf(".prototype") >= 0) {
|
|
||||||
context = null;
|
|
||||||
} else {
|
|
||||||
vm.runInContext(Object.keys(context).map(function(name) {
|
|
||||||
return "delete " + name;
|
|
||||||
}).join("\n"), context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -969,7 +969,7 @@ function errorln(msg) {
|
|||||||
process.stderr.write("\n");
|
process.stderr.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function try_beautify(code, result, printfn) {
|
function try_beautify(code, toplevel, result, printfn) {
|
||||||
var beautified = UglifyJS.minify(code, {
|
var beautified = UglifyJS.minify(code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
@@ -981,7 +981,7 @@ function try_beautify(code, result, printfn) {
|
|||||||
if (beautified.error) {
|
if (beautified.error) {
|
||||||
printfn("// !!! beautify failed !!!");
|
printfn("// !!! beautify failed !!!");
|
||||||
printfn(beautified.error.stack);
|
printfn(beautified.error.stack);
|
||||||
} else if (sandbox.same_stdout(sandbox.run_code(beautified.code), result)) {
|
} else if (sandbox.same_stdout(sandbox.run_code(beautified.code, toplevel), result)) {
|
||||||
printfn("// (beautified)");
|
printfn("// (beautified)");
|
||||||
printfn(beautified.code);
|
printfn(beautified.code);
|
||||||
return;
|
return;
|
||||||
@@ -1009,7 +1009,7 @@ function log_suspects(minify_options, component) {
|
|||||||
errorln("Error testing options." + component + "." + name);
|
errorln("Error testing options." + component + "." + name);
|
||||||
errorln(result.error.stack);
|
errorln(result.error.stack);
|
||||||
} else {
|
} else {
|
||||||
var r = sandbox.run_code(result.code);
|
var r = sandbox.run_code(result.code, m.toplevel);
|
||||||
return sandbox.same_stdout(original_result, r);
|
return sandbox.same_stdout(original_result, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1031,7 +1031,7 @@ function log_rename(options) {
|
|||||||
errorln("Error testing options.rename");
|
errorln("Error testing options.rename");
|
||||||
errorln(result.error.stack);
|
errorln(result.error.stack);
|
||||||
} else {
|
} else {
|
||||||
var r = sandbox.run_code(result.code);
|
var r = sandbox.run_code(result.code, m.toplevel);
|
||||||
if (sandbox.same_stdout(original_result, r)) {
|
if (sandbox.same_stdout(original_result, r)) {
|
||||||
errorln("Suspicious options:");
|
errorln("Suspicious options:");
|
||||||
errorln(" rename");
|
errorln(" rename");
|
||||||
@@ -1045,23 +1045,24 @@ function log(options) {
|
|||||||
errorln("//=============================================================");
|
errorln("//=============================================================");
|
||||||
if (!ok) errorln("// !!!!!! Failed... round " + round);
|
if (!ok) errorln("// !!!!!! Failed... round " + round);
|
||||||
errorln("// original code");
|
errorln("// original code");
|
||||||
try_beautify(original_code, original_result, errorln);
|
try_beautify(original_code, false, original_result, errorln);
|
||||||
errorln();
|
errorln();
|
||||||
errorln();
|
errorln();
|
||||||
errorln("//-------------------------------------------------------------");
|
errorln("//-------------------------------------------------------------");
|
||||||
|
options = JSON.parse(options);
|
||||||
if (typeof uglify_code == "string") {
|
if (typeof uglify_code == "string") {
|
||||||
errorln("// uglified code");
|
errorln("// uglified code");
|
||||||
try_beautify(uglify_code, uglify_result, errorln);
|
try_beautify(uglify_code, options.toplevel, uglify_result, errorln);
|
||||||
errorln();
|
errorln();
|
||||||
errorln();
|
errorln();
|
||||||
errorln("original result:");
|
errorln("original result:");
|
||||||
errorln(typeof original_result == "string" ? original_result : original_result.stack);
|
errorln(errored ? original_result.stack : original_result);
|
||||||
errorln("uglified result:");
|
errorln("uglified result:");
|
||||||
errorln(typeof uglify_result == "string" ? uglify_result : uglify_result.stack);
|
errorln(typeof uglify_result == "string" ? uglify_result : uglify_result.stack);
|
||||||
} else {
|
} else {
|
||||||
errorln("// !!! uglify failed !!!");
|
errorln("// !!! uglify failed !!!");
|
||||||
errorln(uglify_code.stack);
|
errorln(uglify_code.stack);
|
||||||
if (typeof original_result != "string") {
|
if (errored) {
|
||||||
errorln();
|
errorln();
|
||||||
errorln();
|
errorln();
|
||||||
errorln("original stacktrace:");
|
errorln("original stacktrace:");
|
||||||
@@ -1069,7 +1070,6 @@ function log(options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
errorln("minify(options):");
|
errorln("minify(options):");
|
||||||
options = JSON.parse(options);
|
|
||||||
errorln(JSON.stringify(options, null, 2));
|
errorln(JSON.stringify(options, null, 2));
|
||||||
errorln();
|
errorln();
|
||||||
if (!ok && typeof uglify_code == "string") {
|
if (!ok && typeof uglify_code == "string") {
|
||||||
@@ -1084,30 +1084,34 @@ var fallback_options = [ JSON.stringify({
|
|||||||
mangle: false
|
mangle: false
|
||||||
}) ];
|
}) ];
|
||||||
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||||
var original_code, original_result;
|
var original_code, original_result, errored;
|
||||||
var uglify_code, uglify_result, ok;
|
var uglify_code, uglify_result, ok;
|
||||||
for (var round = 1; round <= num_iterations; round++) {
|
for (var round = 1; round <= num_iterations; round++) {
|
||||||
process.stdout.write(round + " of " + num_iterations + "\r");
|
process.stdout.write(round + " of " + num_iterations + "\r");
|
||||||
|
|
||||||
original_code = createTopLevelCode();
|
original_code = createTopLevelCode();
|
||||||
original_result = sandbox.run_code(original_code);
|
var orig_result = [ sandbox.run_code(original_code) ];
|
||||||
(typeof original_result != "string" ? fallback_options : minify_options).forEach(function(options) {
|
errored = typeof orig_result[0] != "string";
|
||||||
uglify_code = UglifyJS.minify(original_code, JSON.parse(options));
|
if (!errored) orig_result.push(sandbox.run_code(original_code, true));
|
||||||
|
(errored ? fallback_options : minify_options).forEach(function(options) {
|
||||||
|
var o = JSON.parse(options);
|
||||||
|
uglify_code = UglifyJS.minify(original_code, o);
|
||||||
|
original_result = orig_result[o.toplevel ? 1 : 0];
|
||||||
if (!uglify_code.error) {
|
if (!uglify_code.error) {
|
||||||
uglify_code = uglify_code.code;
|
uglify_code = uglify_code.code;
|
||||||
uglify_result = sandbox.run_code(uglify_code);
|
uglify_result = sandbox.run_code(uglify_code, o.toplevel);
|
||||||
ok = sandbox.same_stdout(original_result, uglify_result);
|
ok = sandbox.same_stdout(original_result, uglify_result);
|
||||||
} else {
|
} else {
|
||||||
uglify_code = uglify_code.error;
|
uglify_code = uglify_code.error;
|
||||||
if (typeof original_result != "string") {
|
if (errored) {
|
||||||
ok = uglify_code.name == original_result.name;
|
ok = uglify_code.name == original_result.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
||||||
else if (typeof original_result != "string") {
|
else if (errored) {
|
||||||
println("//=============================================================");
|
println("//=============================================================");
|
||||||
println("// original code");
|
println("// original code");
|
||||||
try_beautify(original_code, original_result, println);
|
try_beautify(original_code, o.toplevel, original_result, println);
|
||||||
println();
|
println();
|
||||||
println();
|
println();
|
||||||
println("original result:");
|
println("original result:");
|
||||||
|
|||||||
Reference in New Issue
Block a user