// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/sys/fuzzing/libfuzzer/runner.h"

#include <lib/fdio/spawn.h>
#include <lib/fit/defer.h>
#include <lib/fpromise/single_threaded_executor.h>
#include <lib/syslog/cpp/macros.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/syscalls/object.h>
#include <zircon/time.h>

#include <filesystem>
#include <iostream>
#include <sstream>

#include <openssl/sha.h>
#include <re2/re2.h>

#include "src/lib/files/directory.h"
#include "src/lib/files/eintr_wrapper.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/sys/fuzzing/common/dictionary.h"
#include "src/sys/fuzzing/common/status.h"
#include "src/sys/fuzzing/libfuzzer/stats.h"

namespace fuzzing {
namespace {

using fuchsia::fuzzer::ProcessStats;

const char* kTestInputPath = "/tmp/test_input";
const char* kLiveCorpusPath = "/tmp/live_corpus";
const char* kSeedCorpusPath = "/tmp/seed_corpus";
const char* kTempCorpusPath = "/tmp/temp_corpus";
const char* kDictionaryPath = "/tmp/dictionary";
const char* kResultInputPath = "/tmp/result_input";

// See libFuzzer's |fuzzer::FuzzingOptions|.
constexpr int64_t kLibFuzzerNoErrorExitCode = 0;
constexpr int64_t kLibFuzzerTimeoutExitCode = 70;
constexpr int64_t kLibFuzzerOOMExitCode = 71;

// Returns |one| if |original| is non-zero and less than |one|, otherwise returns |original|.
template <typename T>
T Clamp(T original, const T& one, const char* type, const char* unit, const char* flag) {
  if (!original) {
    return 0;
  }
  if (original < one) {
    FX_LOGS(WARNING) << "libFuzzer does not support " << type << "s of less than 1 " << unit
                     << " for '" << flag << "'.";
    return one;
  }
  return original;
}

// Converts a flag into a libFuzzer command line argument.
template <typename T>
std::string MakeArg(const std::string& flag, T value) {
  std::ostringstream oss;
  oss << "-" << flag << "=" << value;
  return oss.str();
}

void CreateDirectory(const char* pathname) {
  if (!files::CreateDirectory(pathname)) {
    FX_LOGS(FATAL) << "Failed to create '" << pathname << "': " << strerror(errno);
  }
}

// Reads a byte sequence from a file.
Input ReadInputFromFile(const std::string& pathname) {
  std::vector<uint8_t> data;
  if (!files::ReadFileToVector(pathname, &data)) {
    FX_LOGS(FATAL) << "Failed to read input from '" << pathname << "': " << strerror(errno);
  }
  return Input(data);
}

// Writes a byte sequence to a file.
void WriteInputToFile(const Input& input, const std::string& pathname) {
  FX_DCHECK(input.size() < std::numeric_limits<ssize_t>::max());
  const auto* data = reinterpret_cast<const char*>(input.data());
  auto size = static_cast<ssize_t>(input.size());
  if (!files::WriteFile(pathname, data, size)) {
    FX_LOGS(FATAL) << "Failed to write input to '" << pathname << "': " << strerror(errno);
  }
}

std::string MakeFilename(const Input& input) {
  uint8_t digest[SHA_DIGEST_LENGTH];
  SHA1(input.data(), input.size(), digest);
  std::ostringstream filename;
  filename << std::hex;
  for (size_t i = 0; i < SHA_DIGEST_LENGTH; ++i) {
    filename << std::setw(2) << std::setfill('0') << size_t(digest[i]);
  }
  return filename.str();
}

}  // namespace

RunnerPtr LibFuzzerRunner::MakePtr(ExecutorPtr executor) {
  return RunnerPtr(new LibFuzzerRunner(std::move(executor)));
}

LibFuzzerRunner::LibFuzzerRunner(ExecutorPtr executor)
    : Runner(executor), process_(executor), workflow_(this) {
  options_ = Runner::options();
  options_->set_detect_exits(true);
  CreateDirectory(kSeedCorpusPath);
  CreateDirectory(kLiveCorpusPath);
}

ZxPromise<> LibFuzzerRunner::Initialize(std::string pkg_dir, std::vector<std::string> args) {
  // First argument is the subprocess name.
  if (args.empty()) {
    return fpromise::make_promise(
        []() -> ZxResult<> { return fpromise::error(ZX_ERR_INVALID_ARGS); });
  }
  auto args_begin = args.begin();
  cmdline_.push_back(*args_begin++);

  // Rearrange args before '--' so that positional args come before flags. Keep the positional args
  // intact, and copy and erase the rest of the command line.
  auto args_end = std::find(args_begin, args.end(), "--");
  auto positional_end =
      std::partition(args_begin, args_end, [](const std::string& arg) { return arg[0] != '-'; });
  std::copy(positional_end, args.end(), std::back_inserter(cmdline_));
  args = std::vector<std::string>(args_begin, positional_end);

  return Runner::Initialize(std::move(pkg_dir), std::move(args));
}

///////////////////////////////////////////////////////////////
// Corpus-related methods.

zx_status_t LibFuzzerRunner::AddToCorpus(CorpusType corpus_type, Input input) {
  auto filename = MakeFilename(input);
  switch (corpus_type) {
    case CorpusType::SEED:
      if (auto [iter, inserted] = seed_corpus_.insert(filename); inserted) {
        WriteInputToFile(input, files::JoinPath(kSeedCorpusPath, filename));
      }
      break;
    case CorpusType::LIVE:
      if (auto [iter, inserted] = live_corpus_.insert(filename); inserted) {
        WriteInputToFile(input, files::JoinPath(kLiveCorpusPath, filename));
      }
      break;
    default:
      return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

std::vector<Input> LibFuzzerRunner::GetCorpus(CorpusType corpus_type) {
  std::vector<Input> inputs;
  switch (corpus_type) {
    case CorpusType::SEED:
      inputs.reserve(seed_corpus_.size());
      for (const auto& filename : seed_corpus_) {
        inputs.emplace_back(ReadInputFromFile(files::JoinPath(kSeedCorpusPath, filename)));
      }
      break;
    case CorpusType::LIVE:
      inputs.reserve(live_corpus_.size());
      for (const auto& filename : live_corpus_) {
        inputs.emplace_back(ReadInputFromFile(files::JoinPath(kLiveCorpusPath, filename)));
      }
      break;
    default:
      FX_NOTIMPLEMENTED();
  }
  return inputs;
}

void LibFuzzerRunner::ReloadLiveCorpus() {
  live_corpus_.clear();
  std::unordered_set<std::string> dups;
  for (const auto& dir_entry : std::filesystem::directory_iterator(kLiveCorpusPath)) {
    auto filename = dir_entry.path().filename().string();
    if (files::IsFile(files::JoinPath(kSeedCorpusPath, filename))) {
      dups.insert(files::JoinPath(kLiveCorpusPath, filename));
    } else {
      live_corpus_.insert(std::move(filename));
    }
  }
  for (const auto& dup_path : dups) {
    std::filesystem::remove(dup_path);
  }
}

///////////////////////////////////////////////////////////////
// Dictionary-related methods.

zx_status_t LibFuzzerRunner::ParseDictionary(const Input& input) {
  Dictionary dict;
  dict.Configure(options());
  if (!dict.Parse(input)) {
    return ZX_ERR_INVALID_ARGS;
  }
  WriteInputToFile(input, kDictionaryPath);
  has_dictionary_ = true;
  return ZX_OK;
}

Input LibFuzzerRunner::GetDictionaryAsInput() const {
  return has_dictionary_ ? ReadInputFromFile(kDictionaryPath) : Input();
}

///////////////////////////////////////////////////////////////
// Fuzzing workflows.

ZxPromise<Artifact> LibFuzzerRunner::Fuzz() {
  return fpromise::make_promise([this]() -> ZxResult<> {
           if (auto status = AddArgs(); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kLiveCorpusPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kSeedCorpusPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           return fpromise::ok();
         })
      .and_then(RunAsync())
      .and_then([this](Artifact& artifact) {
        ReloadLiveCorpus();
        return fpromise::ok(std::move(artifact));
      })
      .wrap_with(workflow_);
}

ZxPromise<Artifact> LibFuzzerRunner::TryEach(std::vector<Input> inputs) {
  // Write the inputs out to storage for libFuzzer.
  std::filesystem::remove_all(kTempCorpusPath);
  CreateDirectory(kTempCorpusPath);
  std::vector<std::string> input_files;
  input_files.reserve(inputs.size());
  for (auto& input : inputs) {
    auto input_file = files::JoinPath(kTempCorpusPath, MakeFilename(input));
    WriteInputToFile(input, input_file);
    input_files.emplace_back(std::move(input_file));
  }
  inputs.clear();
  return TryFiles(std::move(input_files)).wrap_with(workflow_);
}

ZxPromise<Artifact> LibFuzzerRunner::TryFiles(std::vector<std::string> input_files) {
  print_all_ = true;
  return fpromise::make_promise(
      [this, fut = ZxFuture<Artifact>(),
       input_files = std::move(input_files)](Context& context) mutable -> ZxResult<Artifact> {
        // Large corpora can result in a command line that is too big for `fdio_spawn`. Try
        // inputs in batches.
        while (true) {
          if (!fut) {
            if (input_files.empty()) {
              return fpromise::ok(Artifact(FuzzResult::NO_ERRORS));
            }
            if (auto status = AddArgs(); status != ZX_OK) {
              FX_LOGS(WARNING) << "Failed to add libFuzzer command line flags.";
              return fpromise::error(status);
            }
            std::vector<std::string> deferred;
            zx_status_t status = ZX_OK;
            for (auto& input_file : input_files) {
              if (status == ZX_OK) {
                status = process_.AddArg(input_file);
              }
              if (status != ZX_OK) {
                deferred.emplace_back(std::move(input_file));
              }
            }
            if (!deferred.empty()) {
              FX_LOGS(INFO) << "Will try " << deferred.size()
                            << " remaining input(s) in a subsequent attempt.";
            }
            input_files = std::move(deferred);
            fut = RunAsync();
          }
          if (!fut(context)) {
            return fpromise::pending();
          }
          if (fut.is_error()) {
            return fpromise::error(fut.take_error());
          }
          auto artifact = fut.take_value();
          if (artifact.fuzz_result() != FuzzResult::NO_ERRORS) {
            return fpromise::ok(std::move(artifact));
          }
        }
      });
}

ZxPromise<Artifact> LibFuzzerRunner::ValidateMinimize(Input input) {
  WriteInputToFile(input, kTestInputPath);
  return TryFiles(std::vector<std::string>({kTestInputPath}))
      .and_then([](Artifact& artifact) -> ZxResult<Artifact> {
        if (artifact.fuzz_result() == FuzzResult::NO_ERRORS) {
          FX_LOGS(WARNING) << "Test input did not trigger an error.";
          return fpromise::error(ZX_ERR_INVALID_ARGS);
        }
        return fpromise::ok(std::move(artifact));
      })
      .wrap_with(workflow_, Workflow::Mode::kStart);
}

ZxPromise<Artifact> LibFuzzerRunner::Minimize(Artifact artifact) {
  FX_DCHECK(artifact.has_input());
  WriteInputToFile(artifact.input(), kTestInputPath);
  return fpromise::make_promise([this]() -> ZxResult<> {
           if (auto status = AddArgs(); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg("-minimize_crash=1"); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kTestInputPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           return fpromise::ok();
         })
      .and_then(RunAsync())
      .and_then([](Artifact& artifact) -> ZxResult<Artifact> {
        return fpromise::ok(Artifact(FuzzResult::MINIMIZED, artifact.take_input()));
      })
      .wrap_with(workflow_, Workflow::Mode::kFinish);
}

ZxPromise<Artifact> LibFuzzerRunner::Cleanse(Input input) {
  WriteInputToFile(input, kTestInputPath);
  return fpromise::make_promise([this]() -> ZxResult<> {
           if (auto status = AddArgs(); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg("-cleanse_crash=1"); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kTestInputPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           return fpromise::ok();
         })
      .and_then(RunAsync())
      .and_then([input = std::move(input)](Artifact& artifact) mutable {
        // A quirk of libFuzzer's cleanse workflow is that it returns no error and an empty input if
        // the input doesn't crash or is already "clean", and doesn't distinguish between the two.
        if (artifact.has_input()) {
          input = artifact.take_input();
        }
        return fpromise::ok(Artifact(FuzzResult::CLEANSED, std::move(input)));
      })
      .wrap_with(workflow_);
}

ZxPromise<> LibFuzzerRunner::ValidateMerge() {
  std::vector<std::string> input_files;
  input_files.reserve(seed_corpus_.size());
  for (const auto& filename : seed_corpus_) {
    input_files.emplace_back(files::JoinPath(kSeedCorpusPath, filename));
  }
  return TryFiles(std::move(input_files))
      .and_then([](Artifact& artifact) -> ZxResult<> {
        if (artifact.fuzz_result() != FuzzResult::NO_ERRORS) {
          FX_LOGS(WARNING) << "Seed corpus contains an input that triggers an error: '"
                           << artifact.input().ToHex() << "'";
          return fpromise::error(ZX_ERR_INVALID_ARGS);
        }
        return fpromise::ok();
      })
      .wrap_with(workflow_, Workflow::Mode::kStart);
}

ZxPromise<Artifact> LibFuzzerRunner::Merge() {
  std::filesystem::remove_all(kTempCorpusPath);
  CreateDirectory(kTempCorpusPath);
  return fpromise::make_promise([this]() -> ZxResult<> {
           if (auto status = AddArgs(); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg("-merge=1"); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kTempCorpusPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kSeedCorpusPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           if (auto status = process_.AddArg(kLiveCorpusPath); status != ZX_OK) {
             return fpromise::error(status);
           }
           return fpromise::ok();
         })
      .and_then(RunAsync())
      .and_then([this](const Artifact& artifact) -> ZxResult<Artifact> {
        std::filesystem::remove_all(kLiveCorpusPath);
        std::filesystem::rename(kTempCorpusPath, kLiveCorpusPath);
        ReloadLiveCorpus();
        return fpromise::ok(Artifact(FuzzResult::MERGED));
      })
      .or_else([](const zx_status_t& status) -> ZxResult<Artifact> {
        std::filesystem::remove_all(kTempCorpusPath);
        return fpromise::error(status);
      })
      .wrap_with(workflow_, Workflow::Mode::kFinish);
}

Status LibFuzzerRunner::CollectStatus() {
  // For libFuzzer, we return the most recently parsed status rather than point-in-time status.
  auto status = CopyStatus(status_);

  // Add other stats.
  auto elapsed = zx::clock::get_monotonic() - start_;
  status.set_elapsed(elapsed.to_nsecs());

  if (process_.IsAlive()) {
    auto stats = process_.GetStats();
    if (stats.is_ok()) {
      std::vector<ProcessStats> process_stats({stats.take_value()});
      status.set_process_stats(std::move(process_stats));
    }
  }

  return status;
}

ZxPromise<> LibFuzzerRunner::Stop() {
  // TODO(https://fxbug.dev/42168245): If libFuzzer-for-Fuchsia watches for something sent to stdin
  // in order to call its |Fuzzer::StaticInterruptCallback|, we could ask libFuzzer to shut itself
  // down. This would guarantee we get all of its output.
  return process_.Kill().and_then(workflow_.Stop());
}

///////////////////////////////////////////////////////////////
// Process-related methods.

zx_status_t LibFuzzerRunner::AddArgs() {
  auto cmdline_iter = cmdline_.begin();
  while (cmdline_iter != cmdline_.end() && *cmdline_iter != "--") {
    if (auto status = process_.AddArg(*cmdline_iter++); status != ZX_OK) {
      return status;
    }
  }
  if (auto runs = options_->runs(); runs != kDefaultRuns) {
    if (auto status = process_.AddArg(MakeArg("runs", options_->runs())); status != ZX_OK) {
      return status;
    }
  }
  if (auto max_total_time = options_->max_total_time(); max_total_time != kDefaultMaxTotalTime) {
    max_total_time = Clamp(max_total_time, kOneSecond, "duration", "second", "max_total_time");
    options_->set_max_total_time(max_total_time);
    if (auto status = process_.AddArg(MakeArg("max_total_time", max_total_time / kOneSecond));
        status != ZX_OK) {
      return status;
    }
  }
  if (auto seed = options_->seed(); seed != kDefaultSeed) {
    if (auto status = process_.AddArg(MakeArg("seed", seed)); status != ZX_OK) {
      return status;
    }
  }
  if (auto max_input_size = options_->max_input_size(); max_input_size != kDefaultMaxInputSize) {
    if (auto status = process_.AddArg(MakeArg("max_len", max_input_size)); status != ZX_OK) {
      return status;
    }
  }
  if (auto mutation_depth = options_->mutation_depth(); mutation_depth != kDefaultMutationDepth) {
    if (auto status = process_.AddArg(MakeArg("mutate_depth", mutation_depth)); status != ZX_OK) {
      return status;
    }
  }
  if (options_->dictionary_level() != kDefaultDictionaryLevel) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the dictionary level.";
  }
  if (!options_->detect_exits()) {
    FX_LOGS(WARNING) << "libFuzzer does not support ignoring process exits.";
  }
  if (options_->detect_leaks()) {
    if (auto status = process_.AddArg(MakeArg("detect_leaks", "1")); status != ZX_OK) {
      return status;
    }
  }
  if (auto run_limit = options_->run_limit(); run_limit != kDefaultRunLimit) {
    run_limit = Clamp(run_limit, kOneSecond, "duration", "second", "run_limit");
    options_->set_run_limit(run_limit);
    if (auto status = process_.AddArg(MakeArg("timeout", run_limit / kOneSecond));
        status != ZX_OK) {
      return status;
    }
  }
  if (auto malloc_limit = options_->malloc_limit(); malloc_limit != kDefaultMallocLimit) {
    malloc_limit = Clamp(malloc_limit, kOneMb, "memory amount", "MB", "malloc_limit");
    options_->set_malloc_limit(malloc_limit);
    if (auto status = process_.AddArg(MakeArg("malloc_limit_mb", malloc_limit / kOneMb));
        status != ZX_OK) {
      return status;
    }
  }
  if (auto oom_limit = options_->oom_limit(); oom_limit != kDefaultOomLimit) {
    oom_limit = Clamp(oom_limit, kOneMb, "memory amount", "MB", "oom_limit");
    options_->set_oom_limit(oom_limit);
    if (auto status = process_.AddArg(MakeArg("rss_limit_mb", oom_limit / kOneMb));
        status != ZX_OK) {
      return status;
    }
  }
  if (auto purge_interval = options_->purge_interval(); purge_interval != kDefaultPurgeInterval) {
    purge_interval = Clamp(purge_interval, kOneSecond, "duration", "second", "purge_interval");
    options_->set_purge_interval(purge_interval);
    if (auto status =
            process_.AddArg(MakeArg("purge_allocator_interval", purge_interval / kOneSecond));
        status != ZX_OK) {
      return status;
    }
  }
  if (options_->malloc_exitcode() != kDefaultMallocExitcode) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the 'malloc_exitcode'.";
  }
  if (options_->death_exitcode() != kDefaultDeathExitcode) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the 'death_exitcode'.";
  }
  if (options_->leak_exitcode() != kDefaultLeakExitcode) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the 'leak_exitcode'.";
  }
  if (options_->oom_exitcode() != kDefaultOomExitcode) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the 'oom_exitcode'.";
  }
  if (options_->pulse_interval() != kDefaultPulseInterval) {
    FX_LOGS(WARNING) << "libFuzzer does not support setting the 'pulse_interval'.";
  }
  if (options_->debug()) {
    if (auto status = process_.AddArg(MakeArg("handle_segv", 0)); status != ZX_OK) {
      return status;
    }
    if (auto status = process_.AddArg(MakeArg("handle_bus", 0)); status != ZX_OK) {
      return status;
    }
    if (auto status = process_.AddArg(MakeArg("handle_ill", 0)); status != ZX_OK) {
      return status;
    }
    if (auto status = process_.AddArg(MakeArg("handle_fpe", 0)); status != ZX_OK) {
      return status;
    }
    if (auto status = process_.AddArg(MakeArg("handle_abrt", 0)); status != ZX_OK) {
      return status;
    }
  }
  if (options_->print_final_stats()) {
    if (auto status = process_.AddArg(MakeArg("print_final_stats", 1)); status != ZX_OK) {
      return status;
    }
  }
  if (options_->use_value_profile()) {
    if (auto status = process_.AddArg(MakeArg("use_value_profile", 1)); status != ZX_OK) {
      return status;
    }
  }
  auto sanitizer_options = options_->sanitizer_options();
  const auto& name = sanitizer_options.name;
  const auto& value = sanitizer_options.value;
  if (!name.empty() && !value.empty()) {
    if (auto status = process_.SetEnvVar(name, value); status != ZX_OK) {
      return status;
    }
  }
  auto output_flags = options_->output_flags();
  size_t close_fd_mask = 0;
  if (bool(output_flags & OutputFlags::CLOSE_STDOUT)) {
    close_fd_mask |= 1;
  }
  if (bool(output_flags & OutputFlags::CLOSE_STDERR)) {
    close_fd_mask |= 2;
  }
  if (close_fd_mask) {
    if (auto status = process_.AddArg(MakeArg("close_fd_mask", close_fd_mask)); status != ZX_OK) {
      return status;
    }
  }
  if (bool(output_flags & OutputFlags::VERBOSE)) {
    if (auto status = process_.AddArg(MakeArg("verbosity", 2)); status != ZX_OK) {
      return status;
    }
  }
  if (has_dictionary_) {
    if (auto status = process_.AddArg(MakeArg("dict", kDictionaryPath)); status != ZX_OK) {
      return status;
    }
  }
  std::filesystem::remove(kResultInputPath);
  result_input_pathname_.clear();
  if (auto status = process_.AddArg(MakeArg("exact_artifact_path", kResultInputPath));
      status != ZX_OK) {
    return status;
  }
  while (cmdline_iter != cmdline_.end()) {
    if (auto status = process_.AddArg(*cmdline_iter++); status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

ZxPromise<Artifact> LibFuzzerRunner::RunAsync() {
  return fpromise::make_promise([this](Context& context) -> ZxResult<> {
           // Nothing is currently written to libFuzzer's stdin or read from its stdout, but they
           // must be available. For certain workflows, libFuzzer re-executes itself using
           // `fdio_spawn` with `FDIO_SPAWN_CLONE_ALL`, which will fail if it cannot clone an fd.
           if (auto status = process_.AddStdinPipe(); status != ZX_OK) {
             FX_LOGS(WARNING) << "Failed to pipe stdin to libFuzzer";
             return fpromise::error(status);
           }
           if (auto status = process_.AddStdoutPipe(); status != ZX_OK) {
             FX_LOGS(WARNING) << "Failed to pipe stdout from libFuzzer";
             return fpromise::error(status);
           }
           if (auto status = process_.AddStderrPipe(); status != ZX_OK) {
             FX_LOGS(WARNING) << "Failed to pipe stderr from libFuzzer";
             return fpromise::error(status);
           }
           if (auto status = process_.AddVmoVdso(); status != ZX_OK) {
             FX_LOGS(WARNING) << "Failed to pipe vDSO from libFuzzer";
             return fpromise::error(status);
           }
           if (auto status = process_.Spawn(); status != ZX_OK) {
             FX_LOGS(WARNING) << "Failed to spawn libFuzzer";
             return fpromise::error(status);
           }
           status_.set_running(true);
           start_ = zx::clock::get_monotonic();
           return fpromise::ok();
         })
      .and_then(ParseOutput())
      .and_then(
          [this, wait = ZxFuture<int64_t>()](Context& context) mutable -> ZxResult<FuzzResult> {
            if (!wait) {
              wait = process_.Wait();
            }
            if (!wait(context)) {
              return fpromise::pending();
            }
            if (wait.is_error()) {
              return fpromise::error(wait.take_error());
            }
            if (fuzz_result_ != FuzzResult::NO_ERRORS) {
              return fpromise::ok(fuzz_result_);
            }
            auto exitcode = wait.take_value();
            switch (exitcode) {
              case kLibFuzzerNoErrorExitCode:
              case ZX_TASK_RETCODE_SYSCALL_KILL:
                return fpromise::ok(FuzzResult::NO_ERRORS);
              case kLibFuzzerOOMExitCode:
              case ZX_TASK_RETCODE_OOM_KILL:
                return fpromise::ok(FuzzResult::OOM);
              case kLibFuzzerTimeoutExitCode:
                return fpromise::ok(FuzzResult::TIMEOUT);
              default:
                return fpromise::ok(FuzzResult::CRASH);
            }
          })
      .or_else([this, kill = ZxFuture<>()](
                   Context& context, const zx_status_t& status) mutable -> ZxResult<FuzzResult> {
        if (!kill) {
          kill = process_.Kill();
        }
        if (!kill(context)) {
          return fpromise::pending();
        }
        return fpromise::error(status);
      })
      .then([this](ZxResult<FuzzResult>& result) -> ZxResult<FuzzResult> {
        status_.set_running(false);
        process_.Reset();
        print_all_ = false;
        pid_ = int64_t(-1);
        fuzz_result_ = FuzzResult::NO_ERRORS;
        return std::move(result);
      })
      .and_then([this](const FuzzResult& fuzz_result) -> ZxResult<Artifact> {
        if (files::IsFile(kResultInputPath)) {
          return fpromise::ok(Artifact(fuzz_result, ReadInputFromFile(kResultInputPath)));
        }
        if (!result_input_pathname_.empty()) {
          return fpromise::ok(Artifact(fuzz_result, ReadInputFromFile(result_input_pathname_)));
        }
        return fpromise::ok(Artifact(fuzz_result));
      });
}

///////////////////////////////////////////////////////////////
// Output parsing methods.

ZxPromise<> LibFuzzerRunner::ParseOutput() {
  std::vector<ZxPromise<>> outputs;
  outputs.push_back(ParseStdout());
  outputs.push_back(ParseStderr());
  return fpromise::join_promise_vector(std::move(outputs))
      .or_else([]() -> ZxResult<std::vector<ZxResult<>>> {
        // Not possible, but needed to transform the joined promise's error type.
        return fpromise::error(ZX_ERR_INTERNAL);
      })
      .and_then([](std::vector<ZxResult<>>& results) -> ZxResult<> {
        for (const auto& result : results) {
          if (result.is_error()) {
            return fpromise::error(result.error());
          }
        }
        return fpromise::ok();
      });
}

ZxPromise<> LibFuzzerRunner::ParseStdout() {
  return fpromise::make_promise(
      [this, read_line = ZxFuture<std::string>()](Context& context) mutable -> ZxResult<> {
        while (true) {
          if (!read_line) {
            read_line = process_.ReadFromStdout();
          }
          if (!read_line(context)) {
            return fpromise::pending();
          }
          if (read_line.is_error()) {
            if (auto status = read_line.error(); status != ZX_ERR_PEER_CLOSED) {
              FX_LOGS(ERROR) << "failed to read libFuzzer stdout: " << zx_status_get_string(status);
              return fpromise::error(status);
            }
            return fpromise::ok();
          }
          auto line = read_line.take_value();
          if (verbose_ && print_all_) {
            std::cout << line << std::endl;
          }
        }
      });
}

ZxPromise<> LibFuzzerRunner::ParseStderr() {
  return fpromise::make_promise(
      [this, read_line = ZxFuture<std::string>()](Context& context) mutable -> ZxResult<> {
        while (true) {
          if (!read_line) {
            read_line = process_.ReadFromStderr();
          }
          if (!read_line(context)) {
            return fpromise::pending();
          }
          if (read_line.is_error()) {
            if (auto status = read_line.error(); status != ZX_ERR_PEER_CLOSED) {
              FX_LOGS(ERROR) << "failed to read libFuzzer stderr: " << zx_status_get_string(status);
              return fpromise::error(status);
            }
            // TODO(https://fxbug.dev/42060461): Rarely, the process output will be truncated. This
            // causes problems for tooling like undercoat. This is the only location in the
            // LibFuzzerRunner that returns `ZX_ERR_IO_INVALID`.
            if (pid_ < 0 && !process_.is_killed()) {
              FX_LOGS(ERROR) << "libFuzzer output terminated prematurely.";
              return fpromise::error(ZX_ERR_IO_INVALID);
            }
            return fpromise::ok();
          }

          auto line = read_line.take_value();
          if (verbose_) {
            std::cerr << line << std::endl;
          }

          // See libFuzzer's |Fuzzer::TryDetectingAMemoryLeak|.
          // This match is ugly, but it's the only message in current libFuzzer that this code can
          // rely on to detect a leak.
          if (line == "INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.") {
            fuzz_result_ = FuzzResult::LEAK;
            continue;
          }

          // When running explicit test inputs, libFuzzer doesn't save artifacts. Record the input
          // name to determine which caused the error.
          re2::StringPiece input(line);
          if (re2::RE2::Consume(&input, "Running: (\\S+)", &result_input_pathname_)) {
            continue;
          }

          if (re2::RE2::Consume(&input, "==(\\d+)==", &pid_)) {
            continue;
          }

          UpdateReason reason;
          if (ParseLibFuzzerStats(line, &reason, &status_)) {
            UpdateMonitors(reason);
          }
        }
      });
}

}  // namespace fuzzing
