Change a few functions that take const {ByteArray,string}& to take ByteSpan.
This is to avoid copying the underlying data when converting data types for those functions.
E.g. there will be no need to copy data from a vector of `Mutant` to execute them.
Another example is that RemoteFileAppend(std::string) used to copy the data to a ByteArray, but not needed after.
Also changes dependent functions that take const vector<{ByteArray,string}>& to take span<const ByteSpan>, and const vector<MutateInputRef>& -> span<const MutateInputRef> following the same spirit.
PiperOrigin-RevId: 877433395
diff --git a/centipede/BUILD b/centipede/BUILD
index 15fc743..f634d7e 100644
--- a/centipede/BUILD
+++ b/centipede/BUILD
@@ -459,6 +459,7 @@
":shared_memory_blob_sequence",
":execution_metadata",
":mutation_data",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
],
)
@@ -486,6 +487,7 @@
":knobs",
":mutation_data",
"@abseil-cpp//absl/base:nullability",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
],
)
@@ -642,6 +644,7 @@
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/synchronization",
"@abseil-cpp//absl/time",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:blob_file",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:hash",
@@ -738,6 +741,7 @@
"@abseil-cpp//absl/strings:str_format",
"@abseil-cpp//absl/synchronization",
"@abseil-cpp//absl/time",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:blob_file",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:hash",
@@ -861,6 +865,7 @@
":stop",
"@abseil-cpp//absl/status",
"@abseil-cpp//absl/status:statusor",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:logging",
],
@@ -1102,6 +1107,7 @@
":centipede_runner_no_main",
":mutation_data",
"@abseil-cpp//absl/base:nullability",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
],
)
@@ -1242,6 +1248,7 @@
":mutation_data",
":runner_result",
":util",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:logging",
],
@@ -1281,6 +1288,7 @@
":centipede_callbacks",
":environment",
":runner_result",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@googletest//:gtest_main",
],
@@ -1458,6 +1466,7 @@
":util",
":workdir",
"@abseil-cpp//absl/base:nullability",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:test_util",
"@googletest//:gtest_main",
@@ -1875,6 +1884,7 @@
"@abseil-cpp//absl/container:flat_hash_map",
"@abseil-cpp//absl/strings:str_format",
"@abseil-cpp//absl/time",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:hash",
"@com_google_fuzztest//common:temp_dir",
@@ -1925,6 +1935,7 @@
"@abseil-cpp//absl/container:flat_hash_set",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/time",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:hash",
"@com_google_fuzztest//common:logging",
diff --git a/centipede/byte_array_mutator.cc b/centipede/byte_array_mutator.cc
index 60834c7..f117eea 100644
--- a/centipede/byte_array_mutator.cc
+++ b/centipede/byte_array_mutator.cc
@@ -22,6 +22,7 @@
#include <utility>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/execution_metadata.h"
#include "./centipede/knobs.h"
#include "./centipede/mutation_data.h"
@@ -322,7 +323,7 @@
const KnobId knob_mutate_or_crossover = Knobs::NewId("mutate_or_crossover");
std::vector<Mutant> ByteArrayMutator::MutateMany(
- const std::vector<MutationInputRef>& inputs, size_t num_mutants) {
+ absl::Span<const MutationInputRef> inputs, size_t num_mutants) {
if (inputs.empty()) abort();
// TODO(xinhaoyuan): Consider metadata in other inputs instead of always the
// first one.
diff --git a/centipede/byte_array_mutator.h b/centipede/byte_array_mutator.h
index cec8208..349ed48 100644
--- a/centipede/byte_array_mutator.h
+++ b/centipede/byte_array_mutator.h
@@ -23,6 +23,7 @@
#include <vector>
#include "absl/base/nullability.h"
+#include "absl/types/span.h"
#include "./centipede/execution_metadata.h"
#include "./centipede/knobs.h"
#include "./centipede/mutation_data.h"
@@ -108,7 +109,7 @@
}
// Takes non-empty `inputs` and produces `num_mutants` mutants.
- std::vector<Mutant> MutateMany(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> MutateMany(absl::Span<const MutationInputRef> inputs,
size_t num_mutants);
using CrossOverFn = void (ByteArrayMutator::*)(ByteArray &,
diff --git a/centipede/centipede.cc b/centipede/centipede.cc
index 2dab183..345af69 100644
--- a/centipede/centipede.cc
+++ b/centipede/centipede.cc
@@ -72,6 +72,7 @@
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#include "absl/types/span.h"
#include "./centipede/binary_info.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/command.h"
@@ -362,7 +363,7 @@
}
}
-bool Centipede::InputPassesFilter(const ByteArray &input) {
+bool Centipede::InputPassesFilter(ByteSpan input) {
if (env_.input_filter.empty()) return true;
WriteToLocalFile(input_filter_path_, input);
bool result = input_filter_cmd_.Execute() == EXIT_SUCCESS;
@@ -371,8 +372,8 @@
}
bool Centipede::ExecuteAndReportCrash(std::string_view binary,
- const std::vector<ByteArray> &input_vec,
- BatchResult &batch_result) {
+ absl::Span<const ByteSpan> input_vec,
+ BatchResult& batch_result) {
bool success = user_callbacks_.Execute(binary, input_vec, batch_result);
if (success) return true;
if (ShouldStop()) {
@@ -427,7 +428,7 @@
}
bool Centipede::RunBatch(
- const std::vector<ByteArray>& input_vec,
+ absl::Span<const ByteSpan> input_vec,
BlobFileWriter* absl_nullable corpus_file,
BlobFileWriter* absl_nullable features_file,
BlobFileWriter* absl_nullable unconditional_features_file) {
@@ -582,11 +583,11 @@
while (!to_rerun.empty()) {
if (ShouldStop()) break;
size_t batch_size = std::min(to_rerun.size(), env_.batch_size);
- std::vector<ByteArray> batch(to_rerun.end() - batch_size, to_rerun.end());
- to_rerun.resize(to_rerun.size() - batch_size);
+ std::vector<ByteSpan> batch(to_rerun.end() - batch_size, to_rerun.end());
if (RunBatch(batch, nullptr, nullptr, features_file.get())) {
UpdateAndMaybeLogStats("rerun-old", 1);
}
+ to_rerun.resize(to_rerun.size() - batch_size);
}
}
@@ -778,7 +779,8 @@
seed_inputs.push_back({0});
}
- RunBatch(seed_inputs, corpus_file, features_file,
+ RunBatch(std::vector<ByteSpan>{seed_inputs.begin(), seed_inputs.end()},
+ corpus_file, features_file,
/*unconditional_features_file=*/nullptr);
FUZZTEST_LOG(INFO) << "Number of input seeds available: "
<< num_seeds_available
@@ -873,10 +875,10 @@
if (ShouldStop()) break;
new_runs += mutants.size();
- std::vector<ByteArray> inputs;
+ std::vector<ByteSpan> inputs;
inputs.reserve(mutants.size());
for (auto& mutant : mutants) {
- inputs.push_back(std::move(mutant.data));
+ inputs.push_back(mutant.data);
}
bool gained_new_coverage =
RunBatch(inputs, corpus_file.get(), features_file.get(), nullptr);
@@ -922,8 +924,8 @@
}
void Centipede::ReportCrash(std::string_view binary,
- const std::vector<ByteArray> &input_vec,
- const BatchResult &batch_result) {
+ absl::Span<const ByteSpan> input_vec,
+ const BatchResult& batch_result) {
FUZZTEST_CHECK_EQ(input_vec.size(), batch_result.results().size());
const size_t suspect_input_idx = std::clamp<size_t>(
@@ -1019,7 +1021,7 @@
<< "Executing inputs one-by-one, trying to find the reproducer";
for (auto input_idx : input_idxs_to_try) {
if (ShouldStop()) break;
- const auto &one_input = input_vec[input_idx];
+ const auto one_input = input_vec[input_idx];
BatchResult one_input_batch_result;
if (!user_callbacks_.Execute(binary, {one_input}, one_input_batch_result) &&
one_input_batch_result.IsInputFailure() &&
diff --git a/centipede/centipede.h b/centipede/centipede.h
index aa25a42..b090b1f 100644
--- a/centipede/centipede.h
+++ b/centipede/centipede.h
@@ -24,6 +24,7 @@
#include "absl/base/nullability.h"
#include "absl/status/status.h"
#include "absl/time/time.h"
+#include "absl/types/span.h"
#include "./centipede/binary_info.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/command.h"
@@ -84,7 +85,7 @@
// * its features are written to `features_file` (if that's non-null).
// Returns true if new features were observed.
// Post-condition: `batch_result.results.size()` == `input_vec.size()`.
- bool RunBatch(const std::vector<ByteArray>& input_vec,
+ bool RunBatch(absl::Span<const ByteSpan> input_vec,
BlobFileWriter* absl_nullable corpus_file,
BlobFileWriter* absl_nullable features_file,
BlobFileWriter* absl_nullable unconditional_features_file);
@@ -140,13 +141,13 @@
size_t batch_index);
// Returns true if `input` passes env_.input_filter.
- bool InputPassesFilter(const ByteArray &input);
+ bool InputPassesFilter(ByteSpan input);
// Executes `binary` with `input_vec` and `batch_result` as input/output.
// If the binary crashes, calls ReportCrash().
// Returns true iff there were no crashes.
bool ExecuteAndReportCrash(std::string_view binary,
- const std::vector<ByteArray> &input_vec,
- BatchResult &batch_result);
+ absl::Span<const ByteSpan> input_vec,
+ BatchResult& batch_result);
// Reports a crash and saves the reproducer to workdir/crashes, if possible.
// `binary` is the binary causing the crash.
// Prints the first `env_.max_num_crash_reports` logs.
@@ -156,8 +157,8 @@
// as a hint when choosing which input to try first.
// Stops early if `EarlyExitRequested()`.
void ReportCrash(std::string_view binary,
- const std::vector<ByteArray> &input_vec,
- const BatchResult &batch_result);
+ absl::Span<const ByteSpan> input_vec,
+ const BatchResult& batch_result);
// Merges shard `shard_index_to_merge` of the corpus in `merge_from_dir`
// into the current corpus.
// Writes added inputs to the current shard.
diff --git a/centipede/centipede_callbacks.cc b/centipede/centipede_callbacks.cc
index 66c6c6c..c37fa85 100644
--- a/centipede/centipede_callbacks.cc
+++ b/centipede/centipede_callbacks.cc
@@ -45,6 +45,7 @@
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#include "absl/types/span.h"
#include "./centipede/binary_info.h"
#include "./centipede/command.h"
#include "./centipede/control_flow.h"
@@ -534,7 +535,7 @@
}
int CentipedeCallbacks::ExecuteCentipedeSancovBinaryWithShmem(
- std::string_view binary, const std::vector<ByteArray>& inputs,
+ std::string_view binary, absl::Span<const ByteSpan> inputs,
BatchResult& batch_result) {
auto start_time = absl::Now();
batch_result.ClearAndResize(inputs.size());
@@ -734,7 +735,7 @@
// See also: MutateInputsFromShmem().
MutationResult CentipedeCallbacks::MutateViaExternalBinary(
- std::string_view binary, const std::vector<MutationInputRef>& inputs,
+ std::string_view binary, absl::Span<const MutationInputRef> inputs,
size_t num_mutants) {
FUZZTEST_CHECK(!env_.has_input_wildcards)
<< "Standalone binary does not support custom mutator";
diff --git a/centipede/centipede_callbacks.h b/centipede/centipede_callbacks.h
index 181fd2a..a4fb2bb 100644
--- a/centipede/centipede_callbacks.h
+++ b/centipede/centipede_callbacks.h
@@ -25,6 +25,7 @@
#include "absl/base/nullability.h"
#include "absl/status/statusor.h"
+#include "absl/types/span.h"
#include "./centipede/binary_info.h"
#include "./centipede/byte_array_mutator.h"
#include "./centipede/command.h"
@@ -68,12 +69,12 @@
// Post-condition:
// `batch_result` has results for every `input`, even on failure.
virtual bool Execute(std::string_view binary,
- const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) = 0;
+ absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) = 0;
// Takes non-empty `inputs` and returns at most `num_mutants` mutated inputs.
- virtual std::vector<Mutant> Mutate(
- const std::vector<MutationInputRef>& inputs, size_t num_mutants) {
+ virtual std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
+ size_t num_mutants) {
return env_.use_legacy_default_mutator
? byte_array_mutator_.MutateMany(inputs, num_mutants)
: fuzztest_mutator_.MutateMany(inputs, num_mutants);
@@ -105,9 +106,9 @@
// Same as ExecuteCentipedeSancovBinary, but uses shared memory.
// Much faster for fast targets since it uses fewer system calls.
- int ExecuteCentipedeSancovBinaryWithShmem(
- std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result);
+ int ExecuteCentipedeSancovBinaryWithShmem(std::string_view binary,
+ absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result);
// Constructs a string CENTIPEDE_RUNNER_FLAGS=":flag1:flag2:...",
// where the flags are determined by `env` and also include `extra_flags`.
@@ -151,7 +152,7 @@
// whether the binary has a custom mutator, and if it does, `mutants` contains
// at most `num_mutants` non-empty mutants.
MutationResult MutateViaExternalBinary(
- std::string_view binary, const std::vector<MutationInputRef> &inputs,
+ std::string_view binary, absl::Span<const MutationInputRef> inputs,
size_t num_mutants);
// Loads the dictionary from `dictionary_path`,
diff --git a/centipede/centipede_callbacks_test.cc b/centipede/centipede_callbacks_test.cc
index 60fb8fc..ad8c68a 100644
--- a/centipede/centipede_callbacks_test.cc
+++ b/centipede/centipede_callbacks_test.cc
@@ -18,6 +18,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/types/span.h"
#include "./centipede/environment.h"
#include "./centipede/runner_result.h"
#include "./common/defs.h"
@@ -28,7 +29,7 @@
class FakeCallbacks : public CentipedeCallbacks {
public:
explicit FakeCallbacks(const Environment& env) : CentipedeCallbacks(env) {}
- bool Execute(std::string_view binary, const std::vector<ByteArray>& inputs,
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
BatchResult& batch_result) override {
return true;
}
diff --git a/centipede/centipede_default_callbacks.cc b/centipede/centipede_default_callbacks.cc
index 67fe09f..3f07174 100644
--- a/centipede/centipede_default_callbacks.cc
+++ b/centipede/centipede_default_callbacks.cc
@@ -23,6 +23,7 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/environment.h"
#include "./centipede/mutation_data.h"
@@ -46,8 +47,8 @@
}
bool CentipedeDefaultCallbacks::Execute(std::string_view binary,
- const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) {
+ absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) {
return ExecuteCentipedeSancovBinaryWithShmem(binary, inputs, batch_result) ==
0;
}
@@ -73,7 +74,7 @@
}
std::vector<Mutant> CentipedeDefaultCallbacks::Mutate(
- const std::vector<MutationInputRef>& inputs, size_t num_mutants) {
+ absl::Span<const MutationInputRef> inputs, size_t num_mutants) {
if (num_mutants == 0) return {};
// In persistent mode, mutation could fail due to previous asynchronous
// failure, thus give it one more chance to mutate in a clean state.
diff --git a/centipede/centipede_default_callbacks.h b/centipede/centipede_default_callbacks.h
index 9fb157f..02fff74 100644
--- a/centipede/centipede_default_callbacks.h
+++ b/centipede/centipede_default_callbacks.h
@@ -26,6 +26,7 @@
#include <vector>
#include "absl/status/statusor.h"
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/environment.h"
#include "./centipede/mutation_data.h"
@@ -40,9 +41,9 @@
explicit CentipedeDefaultCallbacks(const Environment &env);
size_t GetSeeds(size_t num_seeds, std::vector<ByteArray> &seeds) override;
absl::StatusOr<std::string> GetSerializedTargetConfig() override;
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override;
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override;
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override;
private:
diff --git a/centipede/centipede_interface.cc b/centipede/centipede_interface.cc
index cd5e00d..9031169 100644
--- a/centipede/centipede_interface.cc
+++ b/centipede/centipede_interface.cc
@@ -111,12 +111,9 @@
}
ByteSpan blob;
while (blob_reader->Read(blob) == absl::OkStatus()) {
- ByteArray bytes;
- bytes.insert(bytes.begin(), blob.data(), blob.end());
- // TODO(kcc): [impl] add a variant of WriteToLocalFile that accepts Span.
- WriteToLocalFile(tmpfile, bytes);
+ WriteToLocalFile(tmpfile, blob);
std::string command_line = absl::StrReplaceAll(
- env.for_each_blob, {{"%P", tmpfile}, {"%H", Hash(bytes)}});
+ env.for_each_blob, {{"%P", tmpfile}, {"%H", Hash(blob)}});
Command cmd(command_line);
// TODO(kcc): [as-needed] this creates one process per blob.
// If this flag gets active use, we may want to define special cases,
diff --git a/centipede/centipede_test.cc b/centipede/centipede_test.cc
index 9454d34..a034cc1 100644
--- a/centipede/centipede_test.cc
+++ b/centipede/centipede_test.cc
@@ -33,6 +33,7 @@
#include "absl/strings/str_cat.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/centipede_default_callbacks.h"
#include "./centipede/centipede_interface.h"
@@ -61,6 +62,13 @@
using ::testing::Not;
using ::testing::SizeIs;
+inline std::vector<ByteSpan> AsByteSpans(const std::vector<ByteArray>& inputs) {
+ std::vector<ByteSpan> results;
+ results.reserve(inputs.size());
+ for (const auto& input : inputs) results.push_back(input);
+ return results;
+}
+
// A mock for CentipedeCallbacks.
class CentipedeMock : public CentipedeCallbacks {
public:
@@ -68,8 +76,8 @@
// Doesn't execute anything
// Sets `batch_result.results()` based on the values of `inputs`:
// Collects various stats about the inputs, to be checked in tests.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
batch_result.results().clear();
// For every input, we create a 256-element array `counters`, where
// i-th element is the number of bytes with the value 'i' in the input.
@@ -106,7 +114,7 @@
// (the value {0} is produced by the default GetSeeds()).
// Next 65536 mutations are 2-byte sequences {0,0} ... {255, 255}.
// Then repeat 2-byte sequences.
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
std::vector<Mutant> mutants;
mutants.reserve(num_mutants);
@@ -343,14 +351,14 @@
public:
explicit MutateCallbacks(const Environment &env) : CentipedeCallbacks(env) {}
// Will not be called.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
FUZZTEST_LOG(FATAL);
return false;
}
// Will not be called.
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
FUZZTEST_LOG(FATAL);
}
@@ -489,8 +497,8 @@
// Doesn't execute anything.
// All inputs are 1-byte long.
// For an input {X}, the feature output is {X}.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
batch_result.results().resize(inputs.size());
for (size_t i = 0, n = inputs.size(); i < n; ++i) {
FUZZTEST_CHECK_EQ(inputs[i].size(), 1);
@@ -500,7 +508,7 @@
}
// Every consecutive mutation is {number_of_mutations_} (starting from 1).
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
std::vector<Mutant> mutants(num_mutants);
for (auto &mutant : mutants) {
@@ -578,14 +586,14 @@
}
// Executes the target in the normal way.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
return ExecuteCentipedeSancovBinaryWithShmem(env_.binary, inputs,
batch_result) == EXIT_SUCCESS;
}
// Sets the inputs to one of 3 pre-defined values.
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
for (auto &input : inputs) {
if (!seed_inputs_.contains(input.data)) {
@@ -687,8 +695,8 @@
// Doesn't execute anything.
// On certain combinations of {binary,input} returns false.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
bool res = true;
for (const auto &input : inputs) {
if (input.size() != 1) continue;
@@ -706,7 +714,7 @@
}
// Sets the mutants to different 1-byte values.
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
std::vector<Mutant> mutants(num_mutants);
for (auto &mutant : mutants) {
@@ -806,8 +814,8 @@
// Doesn't execute anything.
// Crash when 0th char of input to binary b1 equals `crashing_input_idx_`, but
// only on 1st exec.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
batch_result.ClearAndResize(inputs.size());
bool res = true;
if (!first_pass_) {
@@ -819,7 +827,7 @@
if (input[0] == crashing_input_idx_) {
if (first_pass_) {
first_pass_ = false;
- crashing_input_ = input;
+ crashing_input_ = {input.begin(), input.end()};
// TODO(b/274705740): `num_outputs_read()` is the number of outputs
// that Centipede engine *expects* to have been read from *the
// current BatchResult* by the *particular* implementation of
@@ -839,7 +847,7 @@
}
// Sets the mutants to different 1-byte values.
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
std::vector<Mutant> mutants;
mutants.reserve(num_mutants);
@@ -974,7 +982,7 @@
BatchResult batch_result;
const std::vector<ByteArray> inputs = {{0}};
- ASSERT_TRUE(callbacks.Execute(env.binary, inputs, batch_result));
+ ASSERT_TRUE(callbacks.Execute(env.binary, AsByteSpans(inputs), batch_result));
ASSERT_EQ(batch_result.results().size(), 1);
bool found_startup_cmp_entry = false;
batch_result.results()[0].metadata().ForEachCmpEntry(
@@ -991,15 +999,15 @@
std::thread::id execute_thread_id)
: CentipedeCallbacks(env), execute_thread_id_(execute_thread_id) {}
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
batch_result.ClearAndResize(inputs.size());
thread_check_passed_ = thread_check_passed_ &&
std::this_thread::get_id() == execute_thread_id_;
return true;
}
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
return {num_mutants, {/*data=*/{0}}};
}
@@ -1036,7 +1044,8 @@
BatchResult batch_result;
const std::vector<ByteArray> inputs = {ByteArray{'s', 't', 'k'}};
- ASSERT_FALSE(callbacks.Execute(env.binary, inputs, batch_result));
+ ASSERT_FALSE(
+ callbacks.Execute(env.binary, AsByteSpans(inputs), batch_result));
EXPECT_THAT(batch_result.log(), HasSubstr("Stack limit exceeded"));
EXPECT_EQ(batch_result.failure_description(), "stack-limit-exceeded");
}
@@ -1045,8 +1054,8 @@
public:
using CentipedeCallbacks::CentipedeCallbacks;
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
++execute_count_;
batch_result.ClearAndResize(inputs.size());
batch_result.exit_code() = EXIT_FAILURE;
@@ -1054,7 +1063,7 @@
return false;
}
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
return {num_mutants, {/*data=*/{0}}};
}
@@ -1082,8 +1091,8 @@
public:
using CentipedeCallbacks::CentipedeCallbacks;
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
++execute_count_;
batch_result.ClearAndResize(inputs.size());
batch_result.exit_code() = EXIT_FAILURE;
@@ -1092,7 +1101,7 @@
return false;
}
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
return {num_mutants, {/*data=*/{0}}};
}
@@ -1120,8 +1129,8 @@
public:
using CentipedeCallbacks::CentipedeCallbacks;
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
++execute_count_;
batch_result.ClearAndResize(inputs.size());
batch_result.exit_code() = EXIT_FAILURE;
@@ -1130,7 +1139,7 @@
return false;
}
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
return {num_mutants, {/*data=*/{0}}};
}
@@ -1230,7 +1239,8 @@
env.fork_server = false;
// Test that the process does not get stuck and exits promptly.
- EXPECT_FALSE(callbacks.Execute(env.binary, {{0}}, batch_result));
+ const ByteArray input = {0};
+ EXPECT_FALSE(callbacks.Execute(env.binary, {input}, batch_result));
}
TEST_F(CentipedeWithTemporaryLocalDir, ExecuteEndsAfterCustomFailure) {
@@ -1242,11 +1252,11 @@
{'c', 'u', 's', 't', 'o', 'm'},
{'c', 'u', 's', 't', 'o', 'm'},
};
- EXPECT_FALSE(callbacks.Execute(env.binary, inputs, result));
+ EXPECT_FALSE(callbacks.Execute(env.binary, AsByteSpans(inputs), result));
EXPECT_THAT(result.failure_description(), HasSubstr("custom 0"));
EXPECT_THAT(result.log(), AllOf(HasSubstr("custom failure 0"),
Not(HasSubstr("custom failure 1"))));
- EXPECT_FALSE(callbacks.Execute(env.binary, inputs, result));
+ EXPECT_FALSE(callbacks.Execute(env.binary, AsByteSpans(inputs), result));
EXPECT_THAT(result.failure_description(), HasSubstr("custom 1"));
EXPECT_THAT(result.log(), AllOf(HasSubstr("custom failure 1"),
Not(HasSubstr("custom failure 2"))));
@@ -1262,7 +1272,7 @@
{'s', 'o', 'm', 'e'},
};
ClearEarlyStopRequestAndSetStopTime(absl::InfiniteFuture());
- EXPECT_TRUE(callbacks.Execute(env.binary, inputs, result));
+ EXPECT_TRUE(callbacks.Execute(env.binary, AsByteSpans(inputs), result));
// Match the error log to check for retrying mutation.
EXPECT_DEATH(
[&] {
diff --git a/centipede/corpus.cc b/centipede/corpus.cc
index f3bc001..def1496 100644
--- a/centipede/corpus.cc
+++ b/centipede/corpus.cc
@@ -229,7 +229,7 @@
return subset_to_remove.size();
}
-void Corpus::Add(const ByteArray& data, const FeatureVec& fv,
+void Corpus::Add(ByteSpan data, const FeatureVec& fv,
const ExecutionMetadata& metadata,
const ExecutionResult::Stats& stats, const FeatureSet& fs,
const CoverageFrontier& coverage_frontier) {
@@ -237,7 +237,7 @@
FUZZTEST_CHECK(!data.empty())
<< "Got request to add empty element to corpus: ignoring";
FUZZTEST_CHECK_EQ(records_.size(), weighted_distribution_.size());
- records_.push_back({data, fv, metadata, stats});
+ records_.push_back({{data.begin(), data.end()}, fv, metadata, stats});
// Will be updated by `UpdateWeights`.
weighted_distribution_.AddWeight(0);
}
diff --git a/centipede/corpus.h b/centipede/corpus.h
index 1a1c4c1..72ef3ce 100644
--- a/centipede/corpus.h
+++ b/centipede/corpus.h
@@ -121,7 +121,7 @@
// Adds a corpus element, consisting of 'data' (the input bytes, non-empty),
// 'fv' (the features associated with this input), and execution `metadata`.
// `fs` is used to compute weights of `fv`.
- void Add(const ByteArray& data, const FeatureVec& fv,
+ void Add(ByteSpan data, const FeatureVec& fv,
const ExecutionMetadata& metadata,
const ExecutionResult::Stats& stats, const FeatureSet& fs,
const CoverageFrontier& coverage_frontier);
diff --git a/centipede/crash_deduplication_test.cc b/centipede/crash_deduplication_test.cc
index bd1966e..f878871 100644
--- a/centipede/crash_deduplication_test.cc
+++ b/centipede/crash_deduplication_test.cc
@@ -27,6 +27,7 @@
#include "absl/strings/str_format.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/crash_summary.h"
#include "./centipede/environment.h"
@@ -168,7 +169,7 @@
absl::flat_hash_map<std::string, Crash> crashing_inputs)
: CentipedeCallbacks(env), crashing_inputs_(std::move(crashing_inputs)) {}
- bool Execute(std::string_view binary, const std::vector<ByteArray>& inputs,
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
BatchResult& batch_result) override {
batch_result.ClearAndResize(inputs.size());
for (ByteSpan input : inputs) {
diff --git a/centipede/fuzztest_mutator.cc b/centipede/fuzztest_mutator.cc
index 6985fdf..f46041f 100644
--- a/centipede/fuzztest_mutator.cc
+++ b/centipede/fuzztest_mutator.cc
@@ -140,7 +140,7 @@
}
std::vector<Mutant> FuzzTestMutator::MutateMany(
- const std::vector<MutationInputRef>& inputs, size_t num_mutants) {
+ absl::Span<const MutationInputRef> inputs, size_t num_mutants) {
if (inputs.empty()) abort();
auto& cmp_tables = mutation_metadata_->cmp_tables;
cmp_tables.resize(inputs.size());
diff --git a/centipede/fuzztest_mutator.h b/centipede/fuzztest_mutator.h
index ff204f2..8ee29ae 100644
--- a/centipede/fuzztest_mutator.h
+++ b/centipede/fuzztest_mutator.h
@@ -20,6 +20,7 @@
#include <memory>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/execution_metadata.h"
#include "./centipede/knobs.h"
#include "./centipede/mutation_data.h"
@@ -44,7 +45,7 @@
~FuzzTestMutator();
// Takes non-empty `inputs` and produces `num_mutants` mutants.
- std::vector<Mutant> MutateMany(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> MutateMany(absl::Span<const MutationInputRef> inputs,
size_t num_mutants);
// Adds `dict_entries` to the internal mutation dictionary.
diff --git a/centipede/minimize_crash.cc b/centipede/minimize_crash.cc
index 2f41046..245846c 100644
--- a/centipede/minimize_crash.cc
+++ b/centipede/minimize_crash.cc
@@ -116,7 +116,7 @@
//
const std::vector<Mutant> mutants = callbacks->Mutate(
GetMutationInputRefsFromDataInputs(recent_crashers), env.batch_size);
- std::vector<ByteArray> smaller_mutants;
+ std::vector<ByteSpan> smaller_mutants;
for (const auto &m : mutants) {
if (m.data.size() < min_known_size) smaller_mutants.push_back(m.data);
}
@@ -125,10 +125,10 @@
if (!callbacks->Execute(env.binary, smaller_mutants, batch_result)) {
size_t crash_inputs_idx = batch_result.num_outputs_read();
FUZZTEST_CHECK_LT(crash_inputs_idx, smaller_mutants.size());
- const auto &new_crasher = smaller_mutants[crash_inputs_idx];
+ const auto new_crasher = smaller_mutants[crash_inputs_idx];
FUZZTEST_LOG(INFO) << "Crasher: size: " << new_crasher.size() << ": "
<< AsPrintableString(new_crasher, /*max_len=*/40);
- queue.AddCrasher(new_crasher);
+ queue.AddCrasher({new_crasher.begin(), new_crasher.end()});
}
}
}
diff --git a/centipede/minimize_crash_test.cc b/centipede/minimize_crash_test.cc
index 30a145a..655c222 100644
--- a/centipede/minimize_crash_test.cc
+++ b/centipede/minimize_crash_test.cc
@@ -23,6 +23,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/nullability.h"
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/environment.h"
#include "./centipede/runner_result.h"
@@ -40,10 +41,10 @@
MinimizerMock(const Environment &env) : CentipedeCallbacks(env) {}
// Runs FuzzMe() on every input, imitates failure if FuzzMe() returns true.
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
batch_result.ClearAndResize(inputs.size());
- for (auto &input : inputs) {
+ for (auto input : inputs) {
if (FuzzMe(input)) {
batch_result.exit_code() = EXIT_FAILURE;
return false;
diff --git a/centipede/runner.cc b/centipede/runner.cc
index 4324529..1ccc2f8 100644
--- a/centipede/runner.cc
+++ b/centipede/runner.cc
@@ -49,6 +49,7 @@
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
+#include "absl/types/span.h"
#include "./centipede/byte_array_mutator.h"
#include "./centipede/dispatcher_flag_helper.h"
#include "./centipede/execution_metadata.h"
@@ -327,7 +328,7 @@
std::string RunnerCallbacks::GetSerializedTargetConfig() { return ""; }
bool RunnerCallbacks::Mutate(
- const std::vector<MutationInputRef>& /*inputs*/, size_t /*num_mutants*/,
+ absl::Span<const MutationInputRef> /*inputs*/, size_t /*num_mutants*/,
std::function<void(MutantRef)> /*new_mutant_callback*/) {
RunnerCheck(!HasCustomMutator(),
"Class deriving from RunnerCallbacks must implement Mutate() if "
@@ -358,7 +359,7 @@
return custom_mutator_cb_ != nullptr;
}
- bool Mutate(const std::vector<MutationInputRef>& inputs, size_t num_mutants,
+ bool Mutate(absl::Span<const MutationInputRef> inputs, size_t num_mutants,
std::function<void(MutantRef)> new_mutant_callback) override;
private:
@@ -632,7 +633,7 @@
}
bool LegacyRunnerCallbacks::Mutate(
- const std::vector<MutationInputRef>& inputs, size_t num_mutants,
+ absl::Span<const MutationInputRef> inputs, size_t num_mutants,
std::function<void(MutantRef)> new_mutant_callback) {
if (custom_mutator_cb_ == nullptr) return false;
unsigned int seed = GetRandomSeed();
diff --git a/centipede/runner_interface.h b/centipede/runner_interface.h
index cfbf849..c622daf 100644
--- a/centipede/runner_interface.h
+++ b/centipede/runner_interface.h
@@ -25,6 +25,7 @@
#include <vector>
#include "absl/base/nullability.h"
+#include "absl/types/span.h"
#include "./centipede/mutation_data.h"
#include "./common/defs.h"
@@ -153,7 +154,7 @@
//
// TODO(xinhaoyuan): Consider supporting only_shrink to speed up
// input shrinking.
- virtual bool Mutate(const std::vector<MutationInputRef>& inputs,
+ virtual bool Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants,
std::function<void(MutantRef)> new_mutant_callback);
virtual ~RunnerCallbacks() = default;
diff --git a/centipede/runner_request.cc b/centipede/runner_request.cc
index 6a33cb7..3cdfbad 100644
--- a/centipede/runner_request.cc
+++ b/centipede/runner_request.cc
@@ -17,6 +17,7 @@
#include <cstring>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/execution_metadata.h"
#include "./centipede/mutation_data.h"
#include "./centipede/shared_memory_blob_sequence.h"
@@ -37,8 +38,8 @@
};
// Writes `inputs` to `blobseq`, returns the number of inputs written.
-static size_t WriteInputs(const std::vector<ByteArray> &inputs,
- BlobSequence &blobseq) {
+static size_t WriteInputs(absl::Span<const ByteSpan> inputs,
+ BlobSequence& blobseq) {
size_t num_inputs = inputs.size();
if (!blobseq.Write(kTagNumInputs, num_inputs)) return 0;
size_t result = 0;
@@ -59,8 +60,8 @@
}
// Similar to above, but for mutation inputs.
-static size_t WriteInputs(const std::vector<MutationInputRef> &inputs,
- BlobSequence &blobseq) {
+static size_t WriteInputs(absl::Span<const MutationInputRef> inputs,
+ BlobSequence& blobseq) {
size_t num_inputs = inputs.size();
if (!blobseq.Write(kTagNumInputs, num_inputs)) return 0;
size_t result = 0;
@@ -75,15 +76,15 @@
} // namespace
-size_t RequestExecution(const std::vector<ByteArray> &inputs,
- BlobSequence &blobseq) {
+size_t RequestExecution(absl::Span<const ByteSpan> inputs,
+ BlobSequence& blobseq) {
if (!blobseq.Write({kTagExecution, 0, nullptr})) return 0;
return WriteInputs(inputs, blobseq);
}
size_t RequestMutation(size_t num_mutants,
- const std::vector<MutationInputRef> &inputs,
- BlobSequence &blobseq) {
+ absl::Span<const MutationInputRef> inputs,
+ BlobSequence& blobseq) {
if (!blobseq.Write({kTagMutation, 0, nullptr})) return 0;
if (!blobseq.Write(kTagNumMutants, num_mutants)) return 0;
return WriteInputs(inputs, blobseq);
diff --git a/centipede/runner_request.h b/centipede/runner_request.h
index f95189f..f1d7a5b 100644
--- a/centipede/runner_request.h
+++ b/centipede/runner_request.h
@@ -20,6 +20,7 @@
#include <cstddef>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/execution_metadata.h"
#include "./centipede/mutation_data.h"
#include "./centipede/shared_memory_blob_sequence.h"
@@ -35,14 +36,14 @@
// Sends a request (via `blobseq`) to execute `inputs`.
// Returns the number of sent inputs, which would normally be inputs.size().
-size_t RequestExecution(const std::vector<ByteArray> &inputs,
- BlobSequence &blobseq);
+size_t RequestExecution(absl::Span<const ByteSpan> inputs,
+ BlobSequence& blobseq);
// Sends a request (via `blobseq`) to compute `num_mutants` mutants of `inputs`.
// Returns the number of sent inputs, which would normally be inputs.size().
size_t RequestMutation(size_t num_mutants,
- const std::vector<MutationInputRef> &inputs,
- BlobSequence &blobseq);
+ absl::Span<const MutationInputRef> inputs,
+ BlobSequence& blobseq);
// Returns whether `blob` indicates an execution request.
bool IsExecutionRequest(Blob blob);
diff --git a/centipede/test_coverage_util.cc b/centipede/test_coverage_util.cc
index 2602a58..7a995a0 100644
--- a/centipede/test_coverage_util.cc
+++ b/centipede/test_coverage_util.cc
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/corpus.h"
#include "./centipede/environment.h"
#include "./centipede/feature.h"
@@ -41,7 +42,9 @@
}
BatchResult batch_result;
// Run.
- CBs.Execute(env.binary, byte_array_inputs, batch_result);
+ std::vector<ByteSpan> byte_span_inputs(byte_array_inputs.begin(),
+ byte_array_inputs.end());
+ CBs.Execute(env.binary, byte_span_inputs, batch_result);
// Repackage execution results into a vector of CorpusRecords.
std::vector<CorpusRecord> corpus_records;
diff --git a/centipede/test_coverage_util.h b/centipede/test_coverage_util.h
index 4a61ab3..a338524 100644
--- a/centipede/test_coverage_util.h
+++ b/centipede/test_coverage_util.h
@@ -21,6 +21,7 @@
#include <string_view>
#include <vector>
+#include "absl/types/span.h"
#include "./centipede/centipede_callbacks.h"
#include "./centipede/corpus.h"
#include "./centipede/environment.h"
@@ -43,14 +44,14 @@
class TestCallbacks : public CentipedeCallbacks {
public:
explicit TestCallbacks(const Environment &env) : CentipedeCallbacks(env) {}
- bool Execute(std::string_view binary, const std::vector<ByteArray> &inputs,
- BatchResult &batch_result) override {
+ bool Execute(std::string_view binary, absl::Span<const ByteSpan> inputs,
+ BatchResult& batch_result) override {
int result =
ExecuteCentipedeSancovBinaryWithShmem(binary, inputs, batch_result);
FUZZTEST_CHECK_EQ(EXIT_SUCCESS, result);
return true;
}
- std::vector<Mutant> Mutate(const std::vector<MutationInputRef>& inputs,
+ std::vector<Mutant> Mutate(absl::Span<const MutationInputRef> inputs,
size_t num_mutants) override {
return {};
}
diff --git a/centipede/testing/BUILD b/centipede/testing/BUILD
index 216d83e..9a61fcd 100644
--- a/centipede/testing/BUILD
+++ b/centipede/testing/BUILD
@@ -84,6 +84,7 @@
"@abseil-cpp//absl/base:nullability",
"@abseil-cpp//absl/flags:flag",
"@abseil-cpp//absl/flags:parse",
+ "@abseil-cpp//absl/types:span",
"@com_google_fuzztest//centipede:centipede_runner_no_main",
"@com_google_fuzztest//centipede:mutation_data",
"@com_google_fuzztest//common:defs",
diff --git a/centipede/testing/async_failing_target.cc b/centipede/testing/async_failing_target.cc
index 3d81ebc..b1b8f89 100644
--- a/centipede/testing/async_failing_target.cc
+++ b/centipede/testing/async_failing_target.cc
@@ -31,7 +31,7 @@
return true;
}
- bool Mutate(const std::vector<fuzztest::internal::MutationInputRef>& inputs,
+ bool Mutate(absl::Span<const fuzztest::internal::MutationInputRef> inputs,
size_t num_mutants,
std::function<void(fuzztest::internal::MutantRef)>
new_mutant_callback) override {
diff --git a/centipede/testing/fuzz_target_with_custom_mutator.cc b/centipede/testing/fuzz_target_with_custom_mutator.cc
index 980ab99..ec686ed 100644
--- a/centipede/testing/fuzz_target_with_custom_mutator.cc
+++ b/centipede/testing/fuzz_target_with_custom_mutator.cc
@@ -19,6 +19,7 @@
#include "absl/base/nullability.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
+#include "absl/types/span.h"
#include "./centipede/mutation_data.h"
#include "./centipede/runner_interface.h"
#include "./common/defs.h"
@@ -37,7 +38,7 @@
bool HasCustomMutator() const override { return true; }
- bool Mutate(const std::vector<fuzztest::internal::MutationInputRef>& inputs,
+ bool Mutate(absl::Span<const fuzztest::internal::MutationInputRef> inputs,
size_t num_mutants,
std::function<void(MutantRef)> new_mutant_callback) override {
for (size_t i = 0; i < inputs.size() && i < num_mutants; ++i) {
diff --git a/centipede/util.cc b/centipede/util.cc
index 376d7b4..83da9e7 100644
--- a/centipede/util.cc
+++ b/centipede/util.cc
@@ -226,13 +226,11 @@
return res;
}
-ByteArray PackFeaturesAndHash(const ByteArray &data,
- const FeatureVec &features) {
+ByteArray PackFeaturesAndHash(ByteSpan data, const FeatureVec& features) {
return PackFeaturesAndHashAsRawBytes(data, AsByteSpan(features));
}
-ByteArray PackFeaturesAndHashAsRawBytes(const ByteArray &data,
- ByteSpan features) {
+ByteArray PackFeaturesAndHashAsRawBytes(ByteSpan data, ByteSpan features) {
ByteArray feature_bytes_with_hash(features.size() + kHashLen);
auto hash = Hash(data);
FUZZTEST_CHECK_EQ(hash.size(), kHashLen);
diff --git a/centipede/util.h b/centipede/util.h
index a34feda..ac5e963 100644
--- a/centipede/util.h
+++ b/centipede/util.h
@@ -140,12 +140,10 @@
std::string ExtractHashFromArray(ByteArray &ba);
// Pack {features, Hash(data)} into a byte array.
-ByteArray PackFeaturesAndHash(const ByteArray &data,
- const FeatureVec &features);
+ByteArray PackFeaturesAndHash(ByteSpan data, const FeatureVec& features);
// Pack `features` and the hash of `data` directly from their raw data format.
-ByteArray PackFeaturesAndHashAsRawBytes(const ByteArray &data,
- ByteSpan features);
+ByteArray PackFeaturesAndHashAsRawBytes(ByteSpan data, ByteSpan features);
// Given a `blob` created by `PackFeaturesAndHash`, unpack the features into
// `features` and return the hash.
diff --git a/common/remote_file.cc b/common/remote_file.cc
index b628ad6..a729e0c 100644
--- a/common/remote_file.cc
+++ b/common/remote_file.cc
@@ -30,8 +30,7 @@
absl::Status RemoteFileAppend(RemoteFile *absl_nonnull f,
const std::string &contents) {
- ByteArray contents_ba{contents.cbegin(), contents.cend()};
- return RemoteFileAppend(f, contents_ba);
+ return RemoteFileAppend(f, AsByteSpan(contents));
}
absl::Status RemoteFileRead(RemoteFile *absl_nonnull f, std::string &contents) {
@@ -42,18 +41,11 @@
}
absl::Status RemoteFileSetContents(std::string_view path,
- const ByteArray &contents) {
- ASSIGN_OR_RETURN_IF_NOT_OK(RemoteFile * file, RemoteFileOpen(path, "w"));
- if (file == nullptr) {
- return absl::UnknownError(
- "RemoteFileOpen returned an OK status but a nullptr RemoteFile*");
- }
- RETURN_IF_NOT_OK(RemoteFileAppend(file, contents));
- return RemoteFileClose(file);
+ const std::string& contents) {
+ return RemoteFileSetContents(path, AsByteSpan(contents));
}
-absl::Status RemoteFileSetContents(std::string_view path,
- const std::string &contents) {
+absl::Status RemoteFileSetContents(std::string_view path, ByteSpan contents) {
ASSIGN_OR_RETURN_IF_NOT_OK(RemoteFile * file, RemoteFileOpen(path, "w"));
if (file == nullptr) {
return absl::UnknownError(
diff --git a/common/remote_file.h b/common/remote_file.h
index e59b484..0b70444 100644
--- a/common/remote_file.h
+++ b/common/remote_file.h
@@ -74,13 +74,13 @@
absl::Status RemoteFileSetWriteBufferSize(RemoteFile *absl_nonnull f,
size_t size);
-// Appends bytes from 'ba' to 'f'.
-absl::Status RemoteFileAppend(RemoteFile *absl_nonnull f, const ByteArray &ba);
-
// Appends characters from 'contents' to 'f'.
absl::Status RemoteFileAppend(RemoteFile *absl_nonnull f,
const std::string &contents);
+// Appends bytes from 'contents' to 'f'.
+absl::Status RemoteFileAppend(RemoteFile* absl_nonnull f, ByteSpan contents);
+
// Flushes the file's internal buffer. Some dynamic results of a running
// pipeline are consumed by itself (e.g. shard cross-pollination) and can be
// consumed by external processes (e.g. monitoring): for such files, call this
@@ -99,11 +99,10 @@
// Sets the contents of the file at 'path' to 'contents'.
absl::Status RemoteFileSetContents(std::string_view path,
- const ByteArray &contents);
+ const std::string& contents);
// Sets the contents of the file at 'path' to 'contents'.
-absl::Status RemoteFileSetContents(std::string_view path,
- const std::string &contents);
+absl::Status RemoteFileSetContents(std::string_view path, ByteSpan contents);
// Reads the contents of the file at 'path' into 'contents'.
absl::Status RemoteFileGetContents(std::string_view path, ByteArray &contents);
diff --git a/common/remote_file_oss.cc b/common/remote_file_oss.cc
index fb6f23a..10299f6 100644
--- a/common/remote_file_oss.cc
+++ b/common/remote_file_oss.cc
@@ -90,11 +90,11 @@
return absl::OkStatus();
}
- absl::Status Write(const ByteArray &ba) {
- static constexpr auto elt_size = sizeof(ba[0]);
- const auto elts_to_write = ba.size();
+ absl::Status Write(ByteSpan contents) {
+ static constexpr auto elt_size = sizeof(contents[0]);
+ const auto elts_to_write = contents.size();
const auto elts_written =
- std::fwrite(ba.data(), elt_size, elts_to_write, file_);
+ std::fwrite(contents.data(), elt_size, elts_to_write, file_);
if (elts_written != elts_to_write) {
return absl::UnknownError(absl::StrCat(
"fwrite() wrote less elements that expected, wrote: ", elts_written,
@@ -327,8 +327,8 @@
return static_cast<LocalRemoteFile *>(f)->SetWriteBufSize(size);
}
-absl::Status RemoteFileAppend(RemoteFile *absl_nonnull f, const ByteArray &ba) {
- return static_cast<LocalRemoteFile *>(f)->Write(ba);
+absl::Status RemoteFileAppend(RemoteFile* absl_nonnull f, ByteSpan contents) {
+ return static_cast<LocalRemoteFile*>(f)->Write(contents);
}
absl::Status RemoteFileFlush(RemoteFile *absl_nonnull f) {
diff --git a/fuzztest/internal/centipede_adaptor.cc b/fuzztest/internal/centipede_adaptor.cc
index b323e2f..33b2628 100644
--- a/fuzztest/internal/centipede_adaptor.cc
+++ b/fuzztest/internal/centipede_adaptor.cc
@@ -516,7 +516,7 @@
bool HasCustomMutator() const override { return true; }
- bool Mutate(const std::vector<MutationInputRef>& inputs, size_t num_mutants,
+ bool Mutate(absl::Span<const MutationInputRef> inputs, size_t num_mutants,
std::function<void(MutantRef)> new_mutant_callback) override {
if (inputs.empty()) return false;
cmp_tables.resize(inputs.size());
@@ -1016,7 +1016,7 @@
using fuzztest::internal::CentipedeCallbacks::CentipedeCallbacks;
bool Execute(std::string_view binary,
- const std::vector<fuzztest::internal::ByteArray>& inputs,
+ absl::Span<const fuzztest::internal::ByteSpan> inputs,
fuzztest::internal::BatchResult& batch_result) override {
return false;
}