| // 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. |
| |
| #ifndef SRC_SYS_FUZZING_COMMON_INPUT_H_ |
| #define SRC_SYS_FUZZING_COMMON_INPUT_H_ |
| |
| #include <fuchsia/fuzzer/cpp/fidl.h> |
| #include <limits.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <string> |
| |
| #include "src/lib/fxl/macros.h" |
| #include "src/sys/fuzzing/common/shared-memory.h" |
| |
| namespace fuzzing { |
| |
| using FidlInput = ::fuchsia::fuzzer::Input; |
| |
| // Represents a single fuzzing input. A corpus is a collection of fuzzing inputs. Inputs are either |
| // provided as part of a seed corpus, or generated by mutating existing inputs. |
| class Input final { |
| public: |
| Input() = default; |
| Input(const std::initializer_list<uint8_t>& bytes) : Input(std::vector<uint8_t>(bytes)) {} |
| explicit Input(const std::vector<uint8_t>& bytes) : Input(bytes.data(), bytes.size()) {} |
| explicit Input(const std::string& bytes) : Input(bytes.c_str(), bytes.size()) {} |
| explicit Input(SharedMemory& shmem) : Input(shmem.data(), shmem.size()) {} |
| Input(Input&& other) noexcept { *this = std::move(other); } |
| |
| ~Input() = default; |
| |
| Input& operator=(Input&& other) noexcept; |
| bool operator==(const Input& other) const; |
| bool operator!=(const Input& other) const { return !(*this == other); } |
| |
| const uint8_t* data() const { return data_.get(); } |
| uint8_t* data() { return data_.get(); } |
| size_t size() const { return size_; } |
| size_t capacity() const { return capacity_; } |
| size_t num_features() const { return num_features_; } |
| |
| void set_num_features(size_t num_features) { num_features_ = num_features; } |
| |
| // Returns a hex string representation. Mostly used for testing/debugging. |
| std::string ToHex() const; |
| |
| // Exchanges the internal state of this input with another. |
| void Swap(Input& other); |
| |
| // Creates a copy of this input. |
| Input Duplicate() const; |
| |
| // Makes this object a copy of the |other|. |
| void Duplicate(const Input& other); |
| |
| // Ensures the input has at least the given |capacity|. |
| void Reserve(size_t capacity); |
| |
| // Appends data to this input. The input must have sufficient remaining capacity for |size| bytes. |
| void Write(const void* data, size_t size); |
| void Write(uint8_t one_byte); |
| |
| // Reserves capacity and sets the size of this input to |size| bytes. This method does NOT |
| // initialize the data, but can be used in conjunction with the |data()| accessor to write into |
| // the input. Returns the new size. |
| size_t Resize(size_t size); |
| |
| // Truncates the input if larger than |max_size|. Returns the new size. |
| size_t Truncate(size_t max_size); |
| |
| // Reduces the capacity of this input to its size. Returns the new size. |
| size_t ShrinkToFit(); |
| |
| // Removes all data from this input. |
| void Clear(); |
| |
| private: |
| Input(const void* data, size_t size) { Allocate(size, data, size); } |
| |
| void Allocate(size_t capacity, const void* data = nullptr, size_t size = 0); |
| |
| void StartExport(zx::socket* sender, FidlInput* receiver) const; |
| void FinishExport(const zx::socket& sender) const; |
| |
| std::unique_ptr<uint8_t[]> data_; |
| size_t capacity_ = 0; |
| size_t size_ = 0; |
| size_t num_features_ = 0; |
| |
| FXL_DISALLOW_COPY_AND_ASSIGN(Input); |
| }; |
| |
| } // namespace fuzzing |
| |
| #endif // SRC_SYS_FUZZING_COMMON_INPUT_H_ |