private static boolean validateOptions()

in tools/dexfuzz/src/dexfuzz/Options.java [324:439]


  private static boolean validateOptions() {
    // Deal with option assumptions.
    if (inputFileList.isEmpty()) {
      File seedFile = new File("fuzzingseed.dex");
      if (seedFile.exists()) {
        Log.always("Assuming --input=fuzzingseed.dex");
        inputFileList.add("fuzzingseed.dex");
      } else {
        Log.errorAndQuit("No input given, and couldn't find fuzzingseed.dex!");
        return false;
      }
    }

    if (outputFile.equals("")) {
      Log.always("Assuming --output=fuzzingseed_fuzzed.dex");
      outputFile = "fuzzingseed_fuzzed.dex";
    }


    if (mutationLikelihoods.isEmpty()) {
      File likelihoodsFile = new File("likelihoods.txt");
      if (likelihoodsFile.exists()) {
        Log.always("Assuming --likelihoods=likelihoods.txt ");
        setupMutationLikelihoodTable("likelihoods.txt");
      } else {
        Log.always("Using default likelihoods (see README for values)");
      }
    }

    // Now check for hard failures.
    if (repeat < 1) {
      Log.error("--repeat must be at least 1!");
      return false;
    }
    if (usingProvidedSeed && repeat > 1) {
      Log.error("Cannot use --repeat with --seed");
      return false;
    }
    if (loadMutations && dumpMutations) {
      Log.error("Cannot both load and dump mutations");
      return false;
    }
    if (repeat == 1 && inputFileList.size() > 1) {
      Log.error("Must use --repeat if you have provided more than one input");
      return false;
    }
    if (methodMutations < 0) {
      Log.error("Cannot use --method-mutations with a negative value.");
      return false;
    }
    if (minMethods < 0) {
      Log.error("Cannot use --min-methods with a negative value.");
      return false;
    }
    if (maxMethods < 0) {
      Log.error("Cannot use --max-methods with a negative value.");
      return false;
    }
    if (maxMethods < minMethods) {
      Log.error("Cannot use --max-methods that's smaller than --min-methods");
      return false;
    }
    if (executeOnHost && usingSpecificDevice) {
      Log.error("Cannot use --host and --device!");
      return false;
    }
    if (execute) {
      // When host-execution mode is specified, we don't need to select an architecture.
      if (!executeOnHost) {
        if (!(useArchArm
            || useArchArm64
            || useArchX86
            || useArchX86_64
            || useArchMips
            || useArchMips64)) {
          Log.error("No architecture to execute on was specified!");
          return false;
        }
      } else {
        // TODO: Select the correct architecture. For now, just assume x86.
        useArchX86 = true;
      }
      if ((useArchArm || useArchArm64) && (useArchX86 || useArchX86_64)) {
        Log.error("Did you mean to specify ARM and x86?");
        return false;
      }
      if ((useArchArm || useArchArm64) && (useArchMips || useArchMips64)) {
        Log.error("Did you mean to specify ARM and MIPS?");
        return false;
      }
      if ((useArchX86 || useArchX86_64) && (useArchMips || useArchMips64)) {
        Log.error("Did you mean to specify x86 and MIPS?");
        return false;
      }
      int backends = 0;
      if (useInterpreter) {
        backends++;
      }
      if (useQuick) {
        backends++;
      }
      if (useOptimizing) {
        backends++;
      }
      if (useArchArm && useArchArm64) {
        // Could just be comparing quick-ARM versus quick-ARM64?
        backends++;
      }
      if (backends < 2) {
        Log.error("Not enough backends specified! Try --quick --interpreter!");
        return false;
      }
    }

    return true;
  }