improve false positive detection in ufuzz (#3977)

This commit is contained in:
Alex Lam S.L
2020-06-09 12:07:02 +01:00
committed by GitHub
parent d764b6cc3b
commit 3b273cecac

View File

@@ -1182,45 +1182,60 @@ function fuzzy_match(original, uglified) {
} }
function patch_try_catch(orig, toplevel) { function patch_try_catch(orig, toplevel) {
var code = orig; var stack = [ {
var tries = []; code: orig,
var offset = 0; index: 0,
offset: 0,
tries: [],
} ];
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)]+)\)|}\s*finally)\s*(?={)/g; var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)]+)\)|}\s*finally)\s*(?={)/g;
var match; while (stack.length) {
while (match = re.exec(code)) { var code = stack[0].code;
var index = match.index + match[0].length + 1; var offset = stack[0].offset;
if (/(?:^|[\s{}):;])try\s*$/.test(match[0])) { var tries = stack[0].tries;
tries.unshift({ try: index - offset }); var match;
continue; re.lastIndex = stack.shift().index;
} while (match = re.exec(code)) {
var insert; var index = match.index + match[0].length + 1;
if (/}\s*finally\s*$/.test(match[0])) { if (/(?:^|[\s{}):;])try\s*$/.test(match[0])) {
tries.shift(); tries.unshift({ try: index - offset });
insert = 'if (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;'; continue;
} else { }
while (tries.length && tries[0].catch) tries.shift(); var insert;
tries[0].catch = index - offset; if (/}\s*finally\s*$/.test(match[0])) {
insert = [ tries.shift();
"if (!" + match[1] + ".ufuzz_var) {", insert = 'if (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;';
match[1] + '.ufuzz_var = "' + match[1] + '";', } else {
match[1] + ".ufuzz_try = " + tries[0].try + ";", while (tries.length && tries[0].catch) tries.shift();
match[1] + ".ufuzz_catch = " + tries[0].catch + ";", tries[0].catch = index - offset;
"UFUZZ_ERROR = " + match[1] + ";", insert = [
"}", "if (!" + match[1] + ".ufuzz_var) {",
"throw " + match[1] + ";", match[1] + '.ufuzz_var = "' + match[1] + '";',
].join("\n"); match[1] + ".ufuzz_try = " + tries[0].try + ";",
} match[1] + ".ufuzz_catch = " + tries[0].catch + ";",
var new_code = code.slice(0, index) + insert + code.slice(index); "UFUZZ_ERROR = " + match[1] + ";",
var result = sandbox.run_code(new_code, toplevel); "}",
if (typeof result != "object" || typeof result.name != "string" || typeof result.message != "string") { "throw " + match[1] + ";",
offset += insert.length; ].join("\n");
code = new_code; }
} else if (result.name == "TypeError" && /'in'/.test(result.message)) { var new_code = code.slice(0, index) + insert + code.slice(index);
index = result.ufuzz_catch; var result = sandbox.run_code(new_code, toplevel);
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index); if (typeof result != "object" || typeof result.name != "string" || typeof result.message != "string") {
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") { if (match[1]) stack.push({
index = result.ufuzz_try; code: code,
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index); index: index,
offset: offset,
tries: JSON.parse(JSON.stringify(tries)),
});
offset += insert.length;
code = new_code;
} else if (result.name == "TypeError" && /'in'/.test(result.message)) {
index = result.ufuzz_catch;
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") {
index = result.ufuzz_try;
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
}
} }
} }
} }