blob: 576cee712586a745be2db6bf613c1942f6774312 [file] [log] [blame]
// 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;
}