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