// Copyright 2019 The Chromium Authors. All rights reserved. #include #include #include #include #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()) { case AppendableApi::AppendCodeUnit: strAppendable.appendCodeUnit(provider.ConsumeIntegral()); break; case AppendableApi::AppendCodePoint: strAppendable.appendCodePoint(provider.ConsumeIntegral()); break; case AppendableApi::AppendString: { std::string appendChrs8( provider.ConsumeRandomLengthString(kMaxAppendLength)); if (appendChrs8.size() == 0) break; std::vector appendChrs(RandomChar16Array( 2, reinterpret_cast(appendChrs8.data()), appendChrs8.size())); strAppendable.appendString(appendChrs.data(), appendChrs.size()); break; } case AppendableApi::ReserveAppendCapacity: strAppendable.reserveAppendCapacity( provider.ConsumeIntegralInRange(0, kMaxReserveSize)); break; case AppendableApi::GetAppendBuffer: { int32_t out_capacity; const auto min_capacity = provider.ConsumeIntegralInRange(1, kScratchBufSize); char16_t* out_buffer = strAppendable.getAppendBuffer( min_capacity, min_capacity + provider.ConsumeIntegralInRange( 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; }