• 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 #include <cstring>
5 #include <stddef.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <memory>
9 #include <utility>
10 #include "fuzzer_utils.h"
11 #include "unicode/brkiter.h"
12 #include "unicode/utext.h"
13 
14 IcuEnvironment* env = new IcuEnvironment();
15 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)16 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
17   UErrorCode status = U_ZERO_ERROR;
18   uint8_t rnd8 = 0;
19   uint16_t rnd16 = 0;
20 
21   if (size < 3) {
22     return 0;
23   }
24   // Extract one and two bytes from fuzzer data for random selection purpose.
25   rnd8 = *data;
26   data++;
27   rnd16 = *(reinterpret_cast<const uint16_t *>(data));
28   data = data + 2;
29   size = size - 3;
30 
31   size_t unistr_size = size/2;
32   std::unique_ptr<char16_t[]> fuzzbuff(new char16_t[unistr_size]);
33   std::memcpy(fuzzbuff.get(), data, unistr_size * 2);
34 
35   UText* fuzzstr = utext_openUChars(nullptr, fuzzbuff.get(), unistr_size, &status);
36 
37   const icu::Locale& locale = GetRandomLocale(rnd16);
38 
39   std::unique_ptr<icu::BreakIterator> bi;
40 
41   switch (rnd8 % 5) {
42     case 0:
43       bi.reset(icu::BreakIterator::createWordInstance(locale, status));
44       break;
45     case 1:
46       bi.reset(icu::BreakIterator::createLineInstance(locale, status));
47       break;
48     case 2:
49       bi.reset(icu::BreakIterator::createCharacterInstance(locale, status));
50       break;
51     case 3:
52       bi.reset(icu::BreakIterator::createSentenceInstance(locale, status));
53       break;
54     case 4:
55       bi.reset(icu::BreakIterator::createTitleInstance(locale, status));
56       break;
57   }
58 
59   bi->setText(fuzzstr, status);
60 
61   if (U_FAILURE(status)) {
62     utext_close(fuzzstr);
63     return 0;
64   }
65 
66   for (int32_t p = bi->first(); p != icu::BreakIterator::DONE; p = bi->next()) {}
67 
68   utext_close(fuzzstr);
69   return 0;
70 }
71 
72