blob: 41255aa4d97c19ba319e2719571348422f34aeb3 [file] [log] [blame]
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Blacklists for fuzzer.
*/
'use strict';
const fs = require('fs');
const path = require('path');
const random = require('./random.js');
const {generatedSloppy, generatedSoftSkipped, generatedSkipped} = require(
'./generated/exceptions.js');
const SKIPPED_FILES = [
// Disabled for unexpected test behavior, specific to d8 shell.
'd8-os.js',
'd8-readbuffer.js',
// Passes JS flags.
'd8-arguments.js',
// Slow tests or tests that are too large to be used as input.
/numops-fuzz-part.*.js/,
'regexp-pcre.js',
'unicode-test.js',
'unicodelctest.js',
'unicodelctest-no-optimization.js',
// Unsupported modules.
/^modules.*\.js/,
// Unsupported property escapes.
/^regexp-property-.*\.js/,
// Bad testcases that just loads a script that always throws errors.
'regress-444805.js',
'regress-crbug-489597.js',
'regress-crbug-620253.js',
// Just recursively loads itself.
'regress-8510.js',
];
const SKIPPED_DIRECTORIES = [
// Slow tests or tests that are too large to be used as input.
'embenchen',
'poppler',
'sqlite',
// Causes lots of failures.
'test262',
// Unavailable debug.Debug.
'v8/test/debugger',
'v8/test/inspector',
// Unsupported modules.
'v8/test/js-perf-test/Modules',
// Contains tests expected to error out on parsing.
'v8/test/message',
// Needs specific dependencies for load of various tests.
'v8/test/mjsunit/tools',
// Unsupported e4x standard.
'mozilla/data/e4x',
// Bails out fast without ReadableStream support.
'spidermonkey/non262/ReadableStream',
];
// Files used with a lower probability.
const SOFT_SKIPPED_FILES = [
// Tests with large binary content.
/^binaryen.*\.js/,
// Tests slow to parse.
// CrashTests:
/^jquery.*\.js/,
// Spidermonkey:
'regress-308085.js',
'regress-74474-002.js',
'regress-74474-003.js',
// V8:
'object-literal.js',
];
// Flags that lead to false positives or that are already passed by default.
const DISALLOWED_FLAGS = [
// Disallowed because features prefixed with "experimental" are not
// stabilized yet and would cause too much noise when enabled.
/^--experimental-.*/,
// Disallowed due to noise. We explicitly add --es-staging to job
// definitions, and all of these features are staged before launch.
/^--harmony-.*/,
// Disallowed because they are passed explicitly on the command line.
'--allow-natives-syntax',
'--debug-code',
'--es-staging',
'--wasm-staging',
'--expose-gc',
'--expose_gc',
'--icu-data-file',
'--random-seed',
// Disallowed due to false positives.
'--check-handle-count',
'--expose-debug-as',
'--expose-natives-as',
'--expose-trigger-failure',
'--mock-arraybuffer-allocator',
'natives', // Used in conjuction with --expose-natives-as.
/^--trace-path.*/,
];
// Flags only used with 25% probability.
const LOW_PROB_FLAGS_PROB = 0.25;
const LOW_PROB_FLAGS = [
// Flags that lead to slow test performance.
/^--gc-interval.*/,
/^--deopt-every-n-times.*/,
];
// Flags printing data, leading to false positives in differential fuzzing.
const DISALLOWED_DIFFERENTIAL_FUZZ_FLAGS = [
/^--gc-interval.*/,
/^--perf.*/,
/^--print.*/,
/^--stress-runs.*/,
/^--trace.*/,
'--expose-externalize-string',
'--interpreted-frames-native-stack',
'--stress-opt',
'--validate-asm',
];
const ALLOWED_RUNTIME_FUNCTIONS = new Set([
// List of allowed runtime functions. Others will be replaced with no-ops.
'ArrayBufferDetach',
'DeoptimizeFunction',
'DeoptimizeNow',
'EnableCodeLoggingForTesting',
'GetUndetectable',
'HeapObjectVerify',
'IsBeingInterpreted',
'NeverOptimizeFunction',
'OptimizeFunctionOnNextCall',
'OptimizeOsr',
'PrepareFunctionForOptimization',
'SetAllocationTimeout',
'SimulateNewspaceFull',
]);
const MAX_FILE_SIZE_BYTES = 128 * 1024; // 128KB
const MEDIUM_FILE_SIZE_BYTES = 32 * 1024; // 32KB
function _findMatch(iterable, candidate) {
for (const entry of iterable) {
if (typeof entry === 'string') {
if (entry === candidate) {
return true;
}
} else {
if (entry.test(candidate)) {
return true;
}
}
}
return false;
}
function _doesntMatch(iterable, candidate) {
return !_findMatch(iterable, candidate);
}
// Convert Windows path separators.
function normalize(testPath) {
return path.normalize(testPath).replace(/\\/g, '/');
}
function isTestSkippedAbs(absPath) {
const basename = path.basename(absPath);
if (_findMatch(SKIPPED_FILES, basename)) {
return true;
}
const normalizedTestPath = normalize(absPath);
for (const entry of SKIPPED_DIRECTORIES) {
if (normalizedTestPath.includes(entry)) {
return true;
}
}
// Avoid OOM/hangs through huge inputs.
const stat = fs.statSync(absPath);
return (stat && stat.size >= MAX_FILE_SIZE_BYTES);
}
function isTestSkippedRel(relPath) {
return generatedSkipped.has(normalize(relPath));
}
// For testing.
function getSoftSkipped() {
return SOFT_SKIPPED_FILES;
}
// For testing.
function getGeneratedSoftSkipped() {
return generatedSoftSkipped;
}
// For testing.
function getGeneratedSloppy() {
return generatedSloppy;
}
function isTestSoftSkippedAbs(absPath) {
const basename = path.basename(absPath);
if (_findMatch(this.getSoftSkipped(), basename)) {
return true;
}
// Graylist medium size files.
const stat = fs.statSync(absPath);
return (stat && stat.size >= MEDIUM_FILE_SIZE_BYTES);
}
function isTestSoftSkippedRel(relPath) {
return this.getGeneratedSoftSkipped().has(normalize(relPath));
}
function isTestSloppyRel(relPath) {
return this.getGeneratedSloppy().has(normalize(relPath));
}
function filterFlags(flags) {
return flags.filter(flag => {
return (
_doesntMatch(DISALLOWED_FLAGS, flag) &&
(_doesntMatch(LOW_PROB_FLAGS, flag) ||
random.choose(LOW_PROB_FLAGS_PROB)));
});
}
function filterDifferentialFuzzFlags(flags) {
return flags.filter(
flag => _doesntMatch(DISALLOWED_DIFFERENTIAL_FUZZ_FLAGS, flag));
}
function isAllowedRuntimeFunction(name) {
if (process.env.APP_NAME != 'd8') {
return false;
}
return ALLOWED_RUNTIME_FUNCTIONS.has(name);
}
module.exports = {
filterDifferentialFuzzFlags: filterDifferentialFuzzFlags,
filterFlags: filterFlags,
getGeneratedSoftSkipped: getGeneratedSoftSkipped,
getGeneratedSloppy: getGeneratedSloppy,
getSoftSkipped: getSoftSkipped,
isAllowedRuntimeFunction: isAllowedRuntimeFunction,
isTestSkippedAbs: isTestSkippedAbs,
isTestSkippedRel: isTestSkippedRel,
isTestSoftSkippedAbs: isTestSoftSkippedAbs,
isTestSoftSkippedRel: isTestSoftSkippedRel,
isTestSloppyRel: isTestSloppyRel,
}