• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2019 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 // Fuzzer for ICU Locales.
5 
6 #include <algorithm>
7 #include <cstddef>
8 #include <cstdint>
9 #include <cstdlib>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "unicode/locid.h"
15 #include "unicode/localpointer.h"
16 #include "unicode/stringpiece.h"
17 
18 #include "locale_util.h"
19 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)20 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
21     if (size < 1) return 0;
22     icu::StringPiece fuzzData(reinterpret_cast<const char *>(data), size);
23     uint8_t rnd = *fuzzData.data();
24     fuzzData.remove_prefix(1);
25     const std::string input = MakeZeroTerminatedInput(
26         (const uint8_t*)(fuzzData.data()), fuzzData.length());
27 
28     icu::Locale locale(input.c_str());
29     UErrorCode status = U_ZERO_ERROR;
30     switch(rnd % 8) {
31         case 0:
32             locale.addLikelySubtags(status);
33             break;
34         case 1:
35             locale.minimizeSubtags(status);
36             break;
37         case 2:
38             locale.canonicalize(status);
39             break;
40         case 3:
41             {
42                 icu::LocalPointer<icu::StringEnumeration> senum(
43                     locale.createKeywords(status), status);
44                 while (U_SUCCESS(status) &&
45                        (senum->next(nullptr, status)) != nullptr) {
46                     // noop
47                 }
48             }
49             break;
50         case 4:
51             {
52                 icu::LocalPointer<icu::StringEnumeration> senum(
53                     locale.createUnicodeKeywords(status), status);
54                 while (U_SUCCESS(status) &&
55                        (senum->next(nullptr, status)) != nullptr) {
56                     // noop
57                 }
58             }
59             break;
60         case 5:
61             {
62                 char buf[256];
63                 icu::CheckedArrayByteSink sink(buf, rnd);
64                 locale.toLanguageTag(sink, status);
65             }
66             break;
67         case 6:
68             {
69                 std::set<std::string> keys;
70                 locale.getKeywords<std::string>(
71                     std::insert_iterator<decltype(keys)>(keys, keys.begin()),
72                     status);
73                 if (U_SUCCESS(status)) {
74                     char buf[256];
75                     icu::CheckedArrayByteSink sink(buf, rnd);
76                     for (std::set<std::string>::iterator it=keys.begin();
77                          it!=keys.end();
78                          ++it) {
79                         locale.getKeywordValue(
80                             icu::StringPiece(it->c_str(), it->length()), sink,
81                             status);
82                     }
83                 }
84             }
85             break;
86         case 7:
87             {
88                 std::set<std::string> keys;
89                 locale.getUnicodeKeywords<std::string>(
90                     std::insert_iterator<decltype(keys)>(keys, keys.begin()),
91                     status);
92                 if (U_SUCCESS(status)) {
93                     char buf[256];
94                     icu::CheckedArrayByteSink sink(buf, rnd);
95                     for (std::set<std::string>::iterator it=keys.begin();
96                          it!=keys.end();
97                          ++it) {
98                         locale.getUnicodeKeywordValue(
99                             icu::StringPiece(it->c_str(), it->length()), sink,
100                             status);
101                     }
102                 }
103             }
104             break;
105         default:
106           break;
107     }
108     return EXIT_SUCCESS;
109 }
110