• 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 ucasemap.
5 
6 #include <cstring>
7 #include <functional>
8 #include <memory>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include "fuzzer_utils.h"
12 #include "unicode/ucasemap.h"
13 
14 IcuEnvironment* env = new IcuEnvironment();
15 
16 template<typename T>
17 using deleted_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;
18 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)19 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
20   UErrorCode status = U_ZERO_ERROR;
21   uint8_t rnd8 = 0;
22   uint16_t rnd16 = 0;
23   uint32_t rnd32 = 0;
24 
25   if (size < 7) {
26     return 0;
27   }
28   // Extract one, two, and four bytes from fuzzer data for random selection
29   // purposes.
30   rnd8 = *data;
31   data++;
32   rnd16 = *(reinterpret_cast<const uint16_t *>(data));
33   data = data + 2;
34   rnd32 = *(reinterpret_cast<const uint32_t *>(data));
35   data = data + 4;
36   size = size - 7;
37 
38   std::unique_ptr<char[]> fuzzbuff(new char[size]);
39   std::memcpy(fuzzbuff.get(), data, size);
40 
41   const icu::Locale& locale = GetRandomLocale(rnd16);
42   uint32_t open_flags = rnd32;
43 
44   deleted_unique_ptr<UCaseMap> csm(
45       ucasemap_open(locale.getName(), open_flags, &status),
46       [](UCaseMap* map) { ucasemap_close(map); });
47 
48   if (U_FAILURE(status)) {
49     return 0;
50   }
51 
52   int32_t dst_size = size * 2;
53   std::unique_ptr<char[]> dst(new char[dst_size]);
54   auto src = reinterpret_cast<const char*>(fuzzbuff.get());
55 
56   switch (rnd8 % 4) {
57     case 0: ucasemap_utf8ToLower(csm.get(), dst.get(), dst_size, src, size,
58                 &status);
59             break;
60     case 1: ucasemap_utf8ToUpper(csm.get(), dst.get(), dst_size, src, size,
61                 &status);
62             break;
63     case 2: ucasemap_utf8ToTitle(csm.get(), dst.get(), dst_size, src, size,
64                 &status);
65             break;
66     case 3: ucasemap_utf8FoldCase(csm.get(), dst.get(), dst_size, src, size,
67                 &status);
68             break;
69   }
70 
71   return 0;
72 }
73