78 lines
2.6 KiB
C++
78 lines
2.6 KiB
C++
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
|
|
#include <fuzzer/FuzzedDataProvider.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <vector>
|
|
#include "third_party/icu/fuzzers/fuzzer_utils.h"
|
|
#include "third_party/icu/source/common/unicode/appendable.h"
|
|
|
|
static IcuEnvironment* env = new IcuEnvironment;
|
|
|
|
constexpr size_t kMaxInitialSize = 64;
|
|
constexpr size_t kMaxReserveSize = 4096;
|
|
constexpr size_t kMaxAppendLength = 64;
|
|
constexpr size_t kMaxAdditionalDesiredSize = 4096;
|
|
|
|
constexpr size_t kScratchBufSize = 4096;
|
|
char16_t scratch_buf[kScratchBufSize];
|
|
|
|
enum class AppendableApi {
|
|
AppendCodeUnit,
|
|
AppendCodePoint,
|
|
AppendString,
|
|
ReserveAppendCapacity,
|
|
GetAppendBuffer,
|
|
kMaxValue = GetAppendBuffer
|
|
};
|
|
|
|
// Entry point for LibFuzzer.
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
FuzzedDataProvider provider(data, size);
|
|
auto str(icu::UnicodeString::fromUTF8(
|
|
provider.ConsumeRandomLengthString(kMaxInitialSize)));
|
|
icu::UnicodeStringAppendable strAppendable(str);
|
|
|
|
while (provider.remaining_bytes() > 0) {
|
|
switch (provider.ConsumeEnum<AppendableApi>()) {
|
|
case AppendableApi::AppendCodeUnit:
|
|
strAppendable.appendCodeUnit(provider.ConsumeIntegral<char16_t>());
|
|
break;
|
|
case AppendableApi::AppendCodePoint:
|
|
strAppendable.appendCodePoint(provider.ConsumeIntegral<UChar32>());
|
|
break;
|
|
case AppendableApi::AppendString: {
|
|
std::string appendChrs8(
|
|
provider.ConsumeRandomLengthString(kMaxAppendLength));
|
|
if (appendChrs8.size() == 0)
|
|
break;
|
|
std::vector<char16_t> appendChrs(RandomChar16Array(
|
|
2, reinterpret_cast<const uint8_t*>(appendChrs8.data()),
|
|
appendChrs8.size()));
|
|
strAppendable.appendString(appendChrs.data(), appendChrs.size());
|
|
break;
|
|
}
|
|
case AppendableApi::ReserveAppendCapacity:
|
|
strAppendable.reserveAppendCapacity(
|
|
provider.ConsumeIntegralInRange<int32_t>(0, kMaxReserveSize));
|
|
break;
|
|
case AppendableApi::GetAppendBuffer: {
|
|
int32_t out_capacity;
|
|
const auto min_capacity =
|
|
provider.ConsumeIntegralInRange<int32_t>(1, kScratchBufSize);
|
|
char16_t* out_buffer = strAppendable.getAppendBuffer(
|
|
min_capacity,
|
|
min_capacity + provider.ConsumeIntegralInRange<int32_t>(
|
|
0, kMaxAdditionalDesiredSize),
|
|
scratch_buf, kScratchBufSize, &out_capacity);
|
|
// Write arbitrary value at the end of the buffer.
|
|
if (out_buffer)
|
|
out_buffer[out_capacity - 1] = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|