diff --git a/icu4c/source/test/fuzzer/Makefile.in b/icu4c/source/test/fuzzer/Makefile.in index e39ac8c4c6a7..f50a82f703ae 100644 --- a/icu4c/source/test/fuzzer/Makefile.in +++ b/icu4c/source/test/fuzzer/Makefile.in @@ -42,6 +42,7 @@ FUZZER_TARGETS = \ list_format_fuzzer locale_fuzzer \ locale_morph_fuzzer \ number_format_fuzzer \ + number_formatter_fuzzer \ relative_date_time_formatter_fuzzer \ rule_based_break_iterator_fuzzer \ ucasemap_fuzzer \ diff --git a/icu4c/source/test/fuzzer/number_formatter_fuzzer.cpp b/icu4c/source/test/fuzzer/number_formatter_fuzzer.cpp new file mode 100644 index 000000000000..660d4be128df --- /dev/null +++ b/icu4c/source/test/fuzzer/number_formatter_fuzzer.cpp @@ -0,0 +1,45 @@ +// © 2019 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include + +#include "fuzzer_utils.h" +#include "unicode/localpointer.h" +#include "unicode/numberformatter.h" + +IcuEnvironment* env = new IcuEnvironment(); + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + UErrorCode status = U_ZERO_ERROR; + + int16_t rnd; + int64_t value; + double doubleValue; + if (size < sizeof(rnd) + sizeof(value) + sizeof(doubleValue)) 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(&value, fuzzData.data(), sizeof(value)); + fuzzData.remove_prefix(sizeof(value)); + + std::memcpy(&doubleValue, fuzzData.data(), sizeof(doubleValue)); + fuzzData.remove_prefix(sizeof(doubleValue)); + + size_t len = fuzzData.size() / sizeof(char16_t); + icu::UnicodeString fuzzstr(false, reinterpret_cast(fuzzData.data()), len); + + icu::number::UnlocalizedNumberFormatter unf = icu::number::NumberFormatter::forSkeleton( + fuzzstr, status); + + icu::number::LocalizedNumberFormatter nf = unf.locale(locale); + + status = U_ZERO_ERROR; + nf.formatInt(value, status); + + status = U_ZERO_ERROR; + nf.formatDouble(doubleValue, status); + return 0; +}