diff --git a/icu4c/source/test/fuzzer/Makefile.in b/icu4c/source/test/fuzzer/Makefile.in index 0fd18ef0b7a..d06c6d690cc 100644 --- a/icu4c/source/test/fuzzer/Makefile.in +++ b/icu4c/source/test/fuzzer/Makefile.in @@ -39,6 +39,7 @@ FUZZER_TARGETS = \ collator_rulebased_fuzzer \ converter_fuzzer date_format_fuzzer \ date_time_pattern_generator_fuzzer \ + dtfmtsym_fuzzer \ list_format_fuzzer locale_fuzzer \ locale_morph_fuzzer \ normalizer2_fuzzer \ diff --git a/icu4c/source/test/fuzzer/dtfmtsym_fuzzer.cpp b/icu4c/source/test/fuzzer/dtfmtsym_fuzzer.cpp new file mode 100644 index 00000000000..680e130f538 --- /dev/null +++ b/icu4c/source/test/fuzzer/dtfmtsym_fuzzer.cpp @@ -0,0 +1,75 @@ +// © 2023 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +// Fuzzer for ICU DateFormatSymbols. + +#include + +#include "fuzzer_utils.h" + +#include "unicode/dtfmtsym.h" +#include "unicode/locid.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + uint16_t rnd; + icu::DateFormatSymbols::DtContextType context; + icu::DateFormatSymbols::DtWidthType width; + if (size < sizeof(rnd) + sizeof(context) + sizeof(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(&context, fuzzData.data(), sizeof(context)); + fuzzData.remove_prefix(sizeof(context)); + icu::DateFormatSymbols::DtContextType context_mod = + static_cast( + context % icu::DateFormatSymbols::DtContextType::DT_CONTEXT_COUNT); +; + std::memcpy(&width, fuzzData.data(), sizeof(width)); + fuzzData.remove_prefix(sizeof(width)); + icu::DateFormatSymbols::DtWidthType width_mod = + static_cast( + width % icu::DateFormatSymbols::DtWidthType::DT_WIDTH_COUNT); + + size_t len = fuzzData.size() / sizeof(char16_t); + icu::UnicodeString text(false, reinterpret_cast(fuzzData.data()), len); + const icu::UnicodeString items[] = { text, text, text, text }; + + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr dfs( + new icu::DateFormatSymbols(locale, status)); + if (U_FAILURE(status)) { + return EXIT_SUCCESS; + } + + int32_t count; + dfs->getEras(count); + dfs->getEraNames(count); + dfs->getNarrowEras(count); + dfs->getMonths(count); + dfs->getShortMonths(count); + dfs->getMonths(count, context, width); + dfs->getMonths(count, context_mod, width_mod); + dfs->getWeekdays(count); + dfs->getShortWeekdays(count); + dfs->getWeekdays(count, context, width); + dfs->getWeekdays(count, context_mod, width_mod); + dfs->getShortWeekdays(count); + dfs->getQuarters(count, context_mod, width_mod); + dfs->getAmPmStrings(count); + + icu::UnicodeString output; + dfs->getTimeSeparatorString(output); + dfs->getYearNames(count, context, width); + dfs->getYearNames(count, context_mod, width_mod); + dfs->getZodiacNames(count, context, width); + dfs->getZodiacNames(count, context_mod, width_mod); + dfs->getLeapMonthPatterns(count); + int32_t count2; + dfs->getZoneStrings(count, count2); + dfs->getLocalPatternChars(output); + + return EXIT_SUCCESS; +}