ICU-22549 Add TimeZoneNames fuzzer

This commit is contained in:
Frank Tang 2023-12-13 17:23:11 -08:00 committed by Frank Yung-Fong Tang
parent 77759422dd
commit 5cf5ec1adb
3 changed files with 78 additions and 4 deletions

View file

@ -1303,11 +1303,16 @@ static void mergeTimeZoneKey(const UnicodeString& mzID, char* result) {
ZNames*
TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) {
if (U_FAILURE(status)) { return nullptr; }
U_ASSERT(mzID.length() <= ZID_KEY_MAX - MZ_PREFIX_LEN);
if (mzID.length() > ZID_KEY_MAX - MZ_PREFIX_LEN) {
status = U_INTERNAL_PROGRAM_ERROR;
return nullptr;
}
char16_t mzIDKey[ZID_KEY_MAX + 1];
mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
U_ASSERT(U_SUCCESS(status)); // already checked length above
if (U_FAILURE(status)) {
return nullptr;
}
mzIDKey[mzID.length()] = 0;
void* mznames = uhash_get(fMZNamesMap, mzIDKey);
@ -1331,7 +1336,10 @@ TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID, UErrorCode& stat
ZNames*
TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID, UErrorCode& status) {
if (U_FAILURE(status)) { return nullptr; }
U_ASSERT(tzID.length() <= ZID_KEY_MAX);
if (tzID.length() > ZID_KEY_MAX) {
status = U_INTERNAL_PROGRAM_ERROR;
return nullptr;
}
char16_t tzIDKey[ZID_KEY_MAX + 1];
int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status);
@ -2248,7 +2256,9 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu
char16_t mzIDKey[ZID_KEY_MAX + 1];
mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
if (U_FAILURE(status)) {
return nullptr;
}
mzIDKey[mzID.length()] = 0;
static UMutex gTZDBNamesMapLock;

View file

@ -47,6 +47,7 @@ FUZZER_TARGETS = \
relative_date_time_formatter_fuzzer \
rule_based_break_iterator_fuzzer \
timezone_create_fuzzer \
time_zone_names_fuzzer \
ucasemap_fuzzer \
uloc_canonicalize_fuzzer \
uloc_for_language_tag_fuzzer \

View file

@ -0,0 +1,63 @@
// © 2023 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
// Fuzzer for TimeZoneNames.
#include <cstring>
#include "fuzzer_utils.h"
#include "unicode/tznames.h"
#include "unicode/locid.h"
void TestNames(icu::TimeZoneNames* names, const icu::UnicodeString& text, UDate date, UTimeZoneNameType type) {
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::StringEnumeration> enumeration(
names->getAvailableMetaZoneIDs(status));
status = U_ZERO_ERROR;
enumeration.reset(
names->getAvailableMetaZoneIDs(text, status));
icu::UnicodeString output;
names->getMetaZoneID(text, date, output);
names->getMetaZoneDisplayName(text, type, output);
names->getTimeZoneDisplayName(text, type, output);
names->getExemplarLocationName(text, output);
names->getDisplayName(text, type, date, output);
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
uint16_t rnd;
UDate date;
UTimeZoneNameType type;
if (size < sizeof(rnd) + sizeof(date) + sizeof(type)) return 0;
icu::StringPiece fuzzData(reinterpret_cast<const char *>(data), size);
std::memcpy(&rnd, fuzzData.data(), sizeof(rnd));
icu::Locale locale = GetRandomLocale(rnd);
fuzzData.remove_prefix(sizeof(rnd));
std::memcpy(&date, fuzzData.data(), sizeof(date));
fuzzData.remove_prefix(sizeof(date));
std::memcpy(&type, fuzzData.data(), sizeof(type));
fuzzData.remove_prefix(sizeof(type));
size_t len = fuzzData.size() / sizeof(char16_t);
icu::UnicodeString text(false, reinterpret_cast<const char16_t*>(fuzzData.data()), len);
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::TimeZoneNames> names(
icu::TimeZoneNames::createInstance(locale, status));
if (U_SUCCESS(status)) {
TestNames(names.get(), text, date, type);
}
status = U_ZERO_ERROR;
names.reset(
icu::TimeZoneNames::createTZDBInstance(locale, status));
if (U_SUCCESS(status)) {
TestNames(names.get(), text, date, type);
}
return EXIT_SUCCESS;
}