improve ufuzz test generation (#4724)

This commit is contained in:
Alex Lam S.L
2021-03-03 07:42:46 +00:00
committed by GitHub
parent 10ca578ee5
commit 04ed818f0a

View File

@@ -184,9 +184,9 @@ var VALUES = [
"25. ", "25. ",
"0x26.toString()", "0x26.toString()",
"NaN", "NaN",
"undefined",
"Infinity",
"null", "null",
"Infinity",
"undefined",
"[]", "[]",
"[,0][1]", // an array with elisions... but this is always false "[,0][1]", // an array with elisions... but this is always false
"([,0].length === 2)", // an array with elisions... this is always true "([,0].length === 2)", // an array with elisions... this is always true
@@ -368,6 +368,7 @@ var generator = false;
var loops = 0; var loops = 0;
var funcs = 0; var funcs = 0;
var clazz = 0; var clazz = 0;
var imports = 0;
var in_class = 0; var in_class = 0;
var called = Object.create(null); var called = Object.create(null);
var labels = 10000; var labels = 10000;
@@ -392,6 +393,10 @@ function appendExport(stmtDepth, allowDefault) {
return ""; return "";
} }
function mayDefer(code) {
return SUPPORT.arrow && rng(50) == 0 ? "void setTimeout(() => (" + code + "), 0)" : code;
}
function createTopLevelCode() { function createTopLevelCode() {
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
block_vars.length = 0; block_vars.length = 0;
@@ -404,6 +409,7 @@ function createTopLevelCode() {
loops = 0; loops = 0;
funcs = 0; funcs = 0;
clazz = 0; clazz = 0;
imports = 0;
in_class = 0; in_class = 0;
called = Object.create(null); called = Object.create(null);
var s = [ var s = [
@@ -419,7 +425,7 @@ function createTopLevelCode() {
} }
}); });
// preceding `null` makes for a cleaner output (empty string still shows up etc) // preceding `null` makes for a cleaner output (empty string still shows up etc)
s.push("console.log(null, a, b, c, Infinity, NaN, undefined);"); s.push(mayDefer("console.log(null, a, b, c, Infinity, NaN, undefined)") + ";");
return s.join("\n"); return s.join("\n");
} }
@@ -925,6 +931,15 @@ function declareVarName(name, no_var) {
return rng(2) ? "let " : "const "; return rng(2) ? "let " : "const ";
} }
function createImportAlias() {
if (rng(10)) return "alias" + imports++;
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
var name = createVarName(MANDATORY);
block_vars.push(name);
unique_vars.length -= 6;
return name;
}
function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth, target) { function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth, target) {
++stmtDepth; ++stmtDepth;
var loop = ++loops; var loop = ++loops;
@@ -1010,7 +1025,12 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
if (/^key/.test(key)) VAR_NAMES.push(key); if (/^key/.test(key)) VAR_NAMES.push(key);
if (rng(3)) { if (rng(3)) {
s += "c = 1 + c; "; s += "c = 1 + c; ";
var name = createVarName(MANDATORY); unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
var name;
do {
name = createVarName(MANDATORY);
} while (name == key);
unique_vars.length -= 6;
s += declareVarName(name) + name + " = expr" + loop + "[" + key + "]; "; s += declareVarName(name) + name + " = expr" + loop + "[" + key + "]; ";
} }
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}"; s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
@@ -1031,30 +1051,20 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}"; return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
case STMT_VAR: case STMT_VAR:
if (SUPPORT.destructuring && stmtDepth == 1 && rng(5) == 0) { if (SUPPORT.destructuring && stmtDepth == 1 && rng(5) == 0) {
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity"); var s = rng(2) ? " " + createImportAlias() : "";
var s = "";
if (rng(2)) {
var name = createVarName(MANDATORY);
block_vars.push(name);
s += " " + name;
}
if (rng(10)) { if (rng(10)) {
if (s) s += ","; if (s) s += ",";
if (rng(2)) { if (rng(2)) {
var name = createVarName(MANDATORY); s += " * as " + createImportAlias();
block_vars.push(name);
s += " * as " + name;
} else { } else {
var names = []; var names = [];
for (var i = rng(4); --i >= 0;) { for (var i = rng(4); --i >= 0;) {
var name = createVarName(MANDATORY); var name = createImportAlias();
block_vars.push(name);
names.push(rng(2) ? getDotKey() + " as " + name : name); names.push(rng(2) ? getDotKey() + " as " + name : name);
} }
s += " { " + names.join(", ") + " }"; s += " { " + names.join(", ") + " }";
} }
} }
unique_vars.length -= 6;
if (s) s += " from"; if (s) s += " from";
return "import" + s + ' "path/to/module.js";'; return "import" + s + ' "path/to/module.js";';
} else if (SUPPORT.destructuring && rng(20) == 0) { } else if (SUPPORT.destructuring && rng(20) == 0) {
@@ -1234,6 +1244,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
case p++: case p++:
return createValue(); return createValue();
case p++: case p++:
if (SUPPORT.destructuring && rng(20) == 0) {
var name = "alias" + rng(imports + 2);
return canThrow && rng(20) == 0 ? name : "typeof " + name + ' != "undefined" && ' + name;
}
case p++: case p++:
return getVarName(); return getVarName();
case p++: case p++:
@@ -1463,9 +1477,9 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
case p++: case p++:
case p++: case p++:
var name = getVarName(); var name = getVarName();
var s = name + "." + getDotKey(); var fn = name + "." + getDotKey();
s = "typeof " + s + ' == "function" && --_calls_ >= 0 && ' + s + createArgs(recurmax, stmtDepth, canThrow); var s = "typeof " + fn + ' == "function" && --_calls_ >= 0 && ' + fn + createArgs(recurmax, stmtDepth, canThrow);
return canThrow && rng(20) == 0 ? s : name + " && " + s; return mayDefer(canThrow && rng(20) == 0 ? s : name + " && " + s);
case p++: case p++:
if (SUPPORT.class && classes.length) switch (rng(20)) { if (SUPPORT.class && classes.length) switch (rng(20)) {
case 0: case 0:
@@ -1497,7 +1511,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
name = rng(3) == 0 ? getVarName() : "f" + rng(funcs + 2); name = rng(3) == 0 ? getVarName() : "f" + rng(funcs + 2);
} while (name in called && !called[name]); } while (name in called && !called[name]);
called[name] = true; called[name] = true;
return "typeof " + name + ' == "function" && --_calls_ >= 0 && ' + name + createArgs(recurmax, stmtDepth, canThrow); return mayDefer("typeof " + name + ' == "function" && --_calls_ >= 0 && ' + name + createArgs(recurmax, stmtDepth, canThrow));
} }
_createExpression.N = p; _createExpression.N = p;
return _createExpression(recurmax, noComma, stmtDepth, canThrow); return _createExpression(recurmax, noComma, stmtDepth, canThrow);
@@ -1557,15 +1571,19 @@ var SAFE_KEYS = [
"a", "a",
"b", "b",
"c", "c",
"undefined",
"null",
"NaN",
"Infinity",
"done",
"foo", "foo",
"NaN",
"null",
"Infinity",
"undefined",
"async",
"done",
"get",
"in", "in",
"length", "length",
"next", "next",
"set",
"static",
"then", "then",
"value", "value",
"var", "var",