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