/src/icu/icu4c/source/test/fuzzer/ucasemap_fuzzer.cpp
Line | Count | Source |
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 | | |
19 | 7.49k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
20 | 7.49k | UErrorCode status = U_ZERO_ERROR; |
21 | 7.49k | uint8_t rnd8 = 0; |
22 | 7.49k | uint16_t rnd16 = 0; |
23 | 7.49k | uint32_t rnd32 = 0; |
24 | | |
25 | 7.49k | if (size < 7) { |
26 | 4 | return 0; |
27 | 4 | } |
28 | | // Extract one, two, and four bytes from fuzzer data for random selection |
29 | | // purposes. |
30 | 7.48k | rnd8 = *data; |
31 | 7.48k | data++; |
32 | 7.48k | rnd16 = *(reinterpret_cast<const uint16_t *>(data)); |
33 | 7.48k | data = data + 2; |
34 | 7.48k | rnd32 = *(reinterpret_cast<const uint32_t *>(data)); |
35 | 7.48k | data = data + 4; |
36 | 7.48k | size = size - 7; |
37 | | |
38 | 7.48k | std::unique_ptr<char[]> fuzzbuff(new char[size]); |
39 | 7.48k | std::memcpy(fuzzbuff.get(), data, size); |
40 | | |
41 | 7.48k | const icu::Locale& locale = GetRandomLocale(rnd16); |
42 | 7.48k | uint32_t open_flags = rnd32; |
43 | | |
44 | 7.48k | deleted_unique_ptr<UCaseMap> csm( |
45 | 7.48k | ucasemap_open(locale.getName(), open_flags, &status), |
46 | 7.48k | [](UCaseMap* map) { ucasemap_close(map); }); |
47 | | |
48 | 7.48k | if (U_FAILURE(status)) { |
49 | 0 | return 0; |
50 | 0 | } |
51 | | |
52 | 7.48k | int32_t dst_size = size * 2; |
53 | 7.48k | std::unique_ptr<char[]> dst(new char[dst_size]); |
54 | 7.48k | const auto* src = reinterpret_cast<const char*>(fuzzbuff.get()); |
55 | | |
56 | 7.48k | switch (rnd8 % 4) { |
57 | 1.18k | case 0: ucasemap_utf8ToLower(csm.get(), dst.get(), dst_size, src, size, |
58 | 1.18k | &status); |
59 | 1.18k | break; |
60 | 1.48k | case 1: ucasemap_utf8ToUpper(csm.get(), dst.get(), dst_size, src, size, |
61 | 1.48k | &status); |
62 | 1.48k | break; |
63 | 4.56k | case 2: ucasemap_utf8ToTitle(csm.get(), dst.get(), dst_size, src, size, |
64 | 4.56k | &status); |
65 | 4.56k | break; |
66 | 247 | case 3: ucasemap_utf8FoldCase(csm.get(), dst.get(), dst_size, src, size, |
67 | 247 | &status); |
68 | 247 | break; |
69 | 7.48k | } |
70 | | |
71 | 7.48k | return 0; |
72 | 7.48k | } |