diff --git a/icu4c/source/test/fuzzer/list_format_fuzzer.cpp b/icu4c/source/test/fuzzer/list_format_fuzzer.cpp index e6b5de3d0491..4821e8516c17 100644 --- a/icu4c/source/test/fuzzer/list_format_fuzzer.cpp +++ b/icu4c/source/test/fuzzer/list_format_fuzzer.cpp @@ -22,19 +22,28 @@ void TestFormat(icu::ListFormatter* listFormat, const icu::UnicodeString* items) } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint16_t rnd; - UListFormatterType type; - UListFormatterWidth width; - if (size < sizeof(rnd) + sizeof(type) + sizeof(width)) return 0; + int32_t raw_type; + int32_t raw_width; + if (size < sizeof(rnd) + sizeof(raw_type) + sizeof(raw_width)) return 0; icu::StringPiece fuzzData(reinterpret_cast(data), size); std::memcpy(&rnd, fuzzData.data(), sizeof(rnd)); icu::Locale locale = GetRandomLocale(rnd); fuzzData.remove_prefix(sizeof(rnd)); - std::memcpy(&type, fuzzData.data(), sizeof(type)); - fuzzData.remove_prefix(sizeof(type)); - std::memcpy(&width, fuzzData.data(), sizeof(width)); - fuzzData.remove_prefix(sizeof(width)); + std::memcpy(&raw_type, fuzzData.data(), sizeof(raw_type)); + fuzzData.remove_prefix(sizeof(raw_type)); + std::memcpy(&raw_width, fuzzData.data(), sizeof(raw_width)); + fuzzData.remove_prefix(sizeof(raw_width)); + + // Ensure non-negative before modulo. + int32_t type_index = raw_type < 0 ? -raw_type : raw_type; + int32_t width_index = raw_width < 0 ? -raw_width : raw_width; + + UListFormatterType type = static_cast( + type_index % (static_cast(ULISTFMT_TYPE_UNITS) + 1)); + UListFormatterWidth width = static_cast( + width_index % (static_cast(ULISTFMT_WIDTH_NARROW) + 1)); size_t len = fuzzData.size() / sizeof(char16_t); icu::UnicodeString text(false, reinterpret_cast(fuzzData.data()), len); @@ -54,16 +63,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { TestFormat(listFormat.get(), items); } - status = U_ZERO_ERROR; - type = static_cast( - static_cast(type) % (static_cast(ULISTFMT_TYPE_UNITS) + 1)); - width = static_cast( - static_cast(width) % (static_cast(ULISTFMT_WIDTH_NARROW) + 1)); - listFormat.reset( - icu::ListFormatter::createInstance(locale, type, width, status)); - if (U_SUCCESS(status)) { - TestFormat(listFormat.get(), items); - } - return EXIT_SUCCESS; }