// 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,
}
