diff --git a/icu4c/source/test/fuzzer/collator_compare_fuzzer.cpp b/icu4c/source/test/fuzzer/collator_compare_fuzzer.cpp index 87b2ea98c2c7..149038e53ece 100644 --- a/icu4c/source/test/fuzzer/collator_compare_fuzzer.cpp +++ b/icu4c/source/test/fuzzer/collator_compare_fuzzer.cpp @@ -1,6 +1,7 @@ // © 2019 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html +#include #include #include "fuzzer_utils.h" @@ -10,23 +11,41 @@ IcuEnvironment* env = new IcuEnvironment(); +static const std::array kStrength = { + icu::Collator::PRIMARY, + icu::Collator::SECONDARY, + icu::Collator::TERTIARY, + icu::Collator::QUATERNARY, + icu::Collator::IDENTICAL +}; + extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { UErrorCode status = U_ZERO_ERROR; - if (size < 2) + uint16_t rnd16; + + if (size < 2 + sizeof(rnd16)) return 0; + std::memcpy(&rnd16, data, sizeof(rnd16)); + size -= sizeof(rnd16); + data += sizeof(rnd16); + icu::Collator::ECollationStrength strength = kStrength[rnd16 % kStrength.size()]; + const icu::Locale& locale = GetRandomLocale(rnd16 / kStrength.size()); + std::unique_ptr compbuff1(new char16_t[size/4]); std::memcpy(compbuff1.get(), data, (size/4)*2); data = data + size/2; std::unique_ptr compbuff2(new char16_t[size/4]); std::memcpy(compbuff2.get(), data, (size/4)*2); + icu::LocalPointer fuzzCollator( - icu::Collator::createInstance(icu::Locale::getUS(), status), status); + icu::Collator::createInstance(locale, status), status); if (U_FAILURE(status)) return 0; - fuzzCollator->setStrength(icu::Collator::TERTIARY); + + fuzzCollator->setStrength(strength); fuzzCollator->compare(compbuff1.get(), size/4, compbuff2.get(), size/4); diff --git a/icu4c/source/test/fuzzer/collator_compare_fuzzer_seed_corpus.txt b/icu4c/source/test/fuzzer/collator_compare_fuzzer_seed_corpus.txt new file mode 100644 index 000000000000..bdc6416a7a4c Binary files /dev/null and b/icu4c/source/test/fuzzer/collator_compare_fuzzer_seed_corpus.txt differ