mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:40:10 +01:00
Replacing direct raw_string_ostream uses. I figure the wrapper should be used more consistently. There are still remaining raw_string_ostream uses that weren't compatible -- I'm continuing to look at those, but felt it was cleaner to have this on its own.
82 lines
2.4 KiB
C++
82 lines
2.4 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <numeric>
|
|
#include <string>
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "testing/util/test_raw_ostream.h"
|
|
#include "toolchain/driver/driver.h"
|
|
|
|
namespace Carbon::Testing {
|
|
|
|
static auto Read(const unsigned char*& data, size_t& size, int& output)
|
|
-> bool {
|
|
if (size < sizeof(output)) {
|
|
return false;
|
|
}
|
|
std::memcpy(&output, data, sizeof(output));
|
|
size -= sizeof(output);
|
|
data += sizeof(output);
|
|
return true;
|
|
}
|
|
|
|
extern "C" auto LLVMFuzzerTestOneInput(const unsigned char* data, size_t size)
|
|
-> int {
|
|
// First use the data to compute the number of arguments. Note that for
|
|
// scaling reasons we don't allow 2^31 arguments, even empty ones. Simply
|
|
// creating the vector of those won't work. We limit this to 2^20 arguments
|
|
// total.
|
|
int num_args;
|
|
if (!Read(data, size, num_args) || num_args < 0 || num_args > (1 << 20)) {
|
|
return 0;
|
|
}
|
|
|
|
// Now use the data to compute the length of each argument. We don't want to
|
|
// exhaust all memory, so bound the search space to using 2^17 bytes of
|
|
// memory for the argument text itself.
|
|
size_t arg_length_sum = 0;
|
|
llvm::SmallVector<int, 16> arg_lengths(num_args);
|
|
for (int& arg_length : arg_lengths) {
|
|
if (!Read(data, size, arg_length) || arg_length < 0) {
|
|
return 0;
|
|
}
|
|
arg_length_sum += arg_length;
|
|
if (arg_length_sum > (1 << 17)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Ensure we have enough data for all the arguments.
|
|
if (size < arg_length_sum) {
|
|
return 0;
|
|
}
|
|
|
|
// Lastly, read the contents of each argument out of the data.
|
|
llvm::SmallVector<llvm::StringRef, 16> args;
|
|
args.reserve(num_args);
|
|
for (int arg_length : arg_lengths) {
|
|
args.push_back(
|
|
llvm::StringRef(reinterpret_cast<const char*>(data), arg_length));
|
|
data += arg_length;
|
|
size -= arg_length;
|
|
}
|
|
|
|
llvm::vfs::InMemoryFileSystem fs;
|
|
TestRawOstream error_stream;
|
|
Driver d(fs, llvm::nulls(), error_stream);
|
|
if (!d.RunFullCommand(args)) {
|
|
if (error_stream.TakeStr().find("ERROR:") == std::string::npos) {
|
|
llvm::errs() << "No error message on a failure!\n";
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
} // namespace Carbon::Testing
|