1 // © 2023 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3
4 // Fuzzer for ICU Normalizer2.
5
6 #include <cstring>
7
8 #include "unicode/normalizer2.h"
9
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)10 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
11 uint16_t rnd;
12 UChar32 char1, char2;
13 // To avoid timeout, limit the input to 5000 bytes
14 if (size > 5000) {
15 size = 5000;
16 }
17 if (size < sizeof(rnd) + sizeof(char1) + sizeof(char2)) return 0;
18 icu::StringPiece fuzzData(reinterpret_cast<const char *>(data), size);
19
20 std::memcpy(&rnd, fuzzData.data(), sizeof(rnd));
21 fuzzData.remove_prefix(sizeof(rnd));
22 std::memcpy(&char1, fuzzData.data(), sizeof(char1));
23 fuzzData.remove_prefix(sizeof(char1));
24 std::memcpy(&char2, fuzzData.data(), sizeof(char2));
25 fuzzData.remove_prefix(sizeof(char2));
26
27 size_t len = fuzzData.size() / sizeof(char16_t);
28 icu::UnicodeString text(false, reinterpret_cast<const char16_t*>(fuzzData.data()), len);
29
30 UErrorCode status = U_ZERO_ERROR;
31 const icu::Normalizer2* norm = nullptr;
32 switch (rnd % 6) {
33 case 0:
34 norm = icu::Normalizer2::getNFCInstance(status);
35 break;
36 case 1:
37 norm = icu::Normalizer2::getNFDInstance(status);
38 break;
39 case 2:
40 norm = icu::Normalizer2::getNFKCInstance(status);
41 break;
42 case 3:
43 norm = icu::Normalizer2::getNFKDInstance(status);
44 break;
45 case 4:
46 norm = icu::Normalizer2::getNFKCCasefoldInstance(status);
47 break;
48 case 5:
49 norm = icu::Normalizer2::getNFKCSimpleCasefoldInstance(status);
50 break;
51 }
52 if (U_SUCCESS(status)) {
53 norm->normalize(text, status);
54 status = U_ZERO_ERROR;
55
56 icu::UnicodeString out;
57
58 norm->normalize(text, out, status);
59 status = U_ZERO_ERROR;
60
61 norm->normalizeSecondAndAppend(out, text, status);
62 status = U_ZERO_ERROR;
63
64 norm->append(out, text, status);
65 status = U_ZERO_ERROR;
66
67 norm->getDecomposition(char1, out);
68 norm->getRawDecomposition(char1, out);
69 norm->composePair(char1, char2);
70 norm->getCombiningClass(char1);
71 norm->isNormalized(text, status);
72 status = U_ZERO_ERROR;
73
74 norm->quickCheck(text, status);
75 status = U_ZERO_ERROR;
76
77 norm->hasBoundaryBefore(char1);
78 norm->hasBoundaryAfter(char1);
79 norm->isInert(char1);
80 }
81
82 return EXIT_SUCCESS;
83 }
84