mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 15:42:14 +00:00
ICU-23095 Add fuzzer for DecimalFormatSymbols
This commit is contained in:
parent
ee90520429
commit
35bb7417ca
3 changed files with 114 additions and 0 deletions
|
@ -40,6 +40,7 @@ FUZZER_TARGETS = \
|
|||
collator_rulebased_fuzzer \
|
||||
converter_fuzzer date_format_fuzzer \
|
||||
date_time_pattern_generator_fuzzer \
|
||||
decimal_format_symbols_fuzzer \
|
||||
dtfmtsym_fuzzer \
|
||||
list_format_fuzzer locale_fuzzer \
|
||||
locale_morph_fuzzer \
|
||||
|
|
95
icu4c/source/test/fuzzer/decimal_format_symbols_fuzzer.cpp
Normal file
95
icu4c/source/test/fuzzer/decimal_format_symbols_fuzzer.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
// © 2025 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
// Fuzzer for DecimalFormatSymbols::DecimalFormatSymbols.
|
||||
|
||||
#include <cstring>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "fuzzer_utils.h"
|
||||
#include "unicode/dcfmtsym.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "uassert.h"
|
||||
|
||||
IcuEnvironment* env = new IcuEnvironment();
|
||||
|
||||
void testMethods(
|
||||
const icu::DecimalFormatSymbols& dfs,
|
||||
icu::DecimalFormatSymbols::ENumberFormatSymbol symbol,
|
||||
UCurrencySpacing spacing,
|
||||
int32_t digit) {
|
||||
dfs.getLocale();
|
||||
dfs.getSymbol(symbol);
|
||||
dfs.getConstSymbol(symbol);
|
||||
dfs.getCurrencyPattern();
|
||||
dfs.getNumberingSystemName();
|
||||
dfs.isCustomCurrencySymbol();
|
||||
dfs.isCustomIntlCurrencySymbol();
|
||||
dfs.getCodePointZero();
|
||||
dfs.getConstDigitSymbol(digit);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
dfs.getPatternForCurrencySpacing(spacing, true, status);
|
||||
dfs.getPatternForCurrencySpacing(spacing, false, status);
|
||||
|
||||
}
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if (size < sizeof(uint16_t)) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t rnd = *(reinterpret_cast<const uint16_t *>(data));
|
||||
const icu::Locale& locale = GetRandomLocale(rnd);
|
||||
data = data + sizeof(uint16_t);
|
||||
size = size - sizeof(uint16_t);
|
||||
|
||||
if (size < sizeof(uint16_t)) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t rnd2 = *(reinterpret_cast<const uint16_t *>(data));
|
||||
std::unique_ptr<const icu::NumberingSystem> ns(CreateRandomNumberingSystem(rnd2, status));
|
||||
U_ASSERT(U_SUCCESS(status));
|
||||
data = data + sizeof(uint16_t);
|
||||
size = size - sizeof(uint16_t);
|
||||
|
||||
if (size < sizeof(int32_t)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t digit = *(reinterpret_cast<const int32_t *>(data));
|
||||
data = data + sizeof(int32_t);
|
||||
size = size - sizeof(int32_t);
|
||||
|
||||
if (size < sizeof(uint8_t)) {
|
||||
return 0;
|
||||
}
|
||||
icu::DecimalFormatSymbols::ENumberFormatSymbol symbol =
|
||||
static_cast<icu::DecimalFormatSymbols::ENumberFormatSymbol>(
|
||||
*data % icu::DecimalFormatSymbols::ENumberFormatSymbol::kFormatSymbolCount);
|
||||
data = data + sizeof(uint8_t);
|
||||
size = size - sizeof(uint8_t);
|
||||
|
||||
if (size < sizeof(uint8_t)) {
|
||||
return 0;
|
||||
}
|
||||
UCurrencySpacing spacing =
|
||||
static_cast<UCurrencySpacing>(
|
||||
*data % UCurrencySpacing::UNUM_CURRENCY_SPACING_COUNT);
|
||||
data = data + sizeof(uint8_t);
|
||||
size = size - sizeof(uint8_t);
|
||||
|
||||
size_t unistr_size = size/2;
|
||||
std::unique_ptr<char16_t[]> fuzzbuff(new char16_t[unistr_size]);
|
||||
std::memcpy(fuzzbuff.get(), data, unistr_size * 2);
|
||||
|
||||
icu::UnicodeString fuzzstr(false, fuzzbuff.get(), unistr_size);
|
||||
icu::DecimalFormatSymbols dfs1(locale, status);
|
||||
U_ASSERT(U_SUCCESS(status));
|
||||
testMethods(dfs1, symbol, spacing, digit);
|
||||
|
||||
icu::DecimalFormatSymbols dfs2(locale, *ns, status);
|
||||
U_ASSERT(U_SUCCESS(status));
|
||||
testMethods(dfs2, symbol, spacing, digit);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/numsys.h"
|
||||
#include "unicode/strenum.h"
|
||||
|
||||
struct IcuEnvironment {
|
||||
IcuEnvironment() {
|
||||
|
@ -21,4 +23,20 @@ const icu::Locale& GetRandomLocale(uint16_t rnd) {
|
|||
return locales[rnd % num_locales];
|
||||
}
|
||||
|
||||
const icu::NumberingSystem* CreateRandomNumberingSystem(uint16_t rnd, UErrorCode &status) {
|
||||
std::unique_ptr<icu::StringEnumeration> se(icu::NumberingSystem::getAvailableNames(status));
|
||||
if (U_FAILURE(status)) return nullptr;
|
||||
int32_t count = se->count(status);
|
||||
if (U_FAILURE(status)) return nullptr;
|
||||
int32_t index = rnd % count;
|
||||
se->reset(status);
|
||||
for (int32_t i = 0; i < index - 1; i++, se->next(nullptr, status)) {
|
||||
// empty
|
||||
}
|
||||
const char* name = se->next(nullptr, status);
|
||||
if (U_FAILURE(status)) return nullptr;
|
||||
return icu::NumberingSystem::createInstanceByName(name, status);
|
||||
}
|
||||
|
||||
|
||||
#endif // FUZZER_UTILS_H_
|
||||
|
|
Loading…
Add table
Reference in a new issue