xref: /aosp_15_r20/external/cronet/third_party/icu/fuzzers/fuzzer_utils.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 
3 #ifndef THIRD_PARTY_ICU_FUZZERS_FUZZER_UTILS_H_
4 #define THIRD_PARTY_ICU_FUZZERS_FUZZER_UTILS_H_
5 
6 #include <assert.h>
7 #include <algorithm>
8 #include <random>
9 
10 #include "base/at_exit.h"
11 #include "base/check.h"
12 #include "base/i18n/icu_util.h"
13 #include "third_party/icu/source/common/unicode/locid.h"
14 #include "third_party/icu/source/common/unicode/uchar.h"
15 #include "third_party/icu/source/common/unicode/unistr.h"
16 
17 struct IcuEnvironment {
IcuEnvironmentIcuEnvironment18   IcuEnvironment() {
19     CHECK(base::i18n::InitializeICU());
20   }
21 };
22 
23 // Create RNG and seed it from data.
CreateRng(const uint8_t * data,size_t size)24 std::mt19937_64 CreateRng(const uint8_t* data, size_t size) {
25   std::mt19937_64 rng;
26   std::string str = std::string(reinterpret_cast<const char*>(data), size);
27   std::size_t data_hash = std::hash<std::string>()(str);
28   rng.seed(data_hash);
29   return rng;
30 }
31 
GetRandomLocale(std::mt19937_64 * rng)32 const icu::Locale& GetRandomLocale(std::mt19937_64* rng) {
33   int32_t num_locales = 0;
34   const icu::Locale* locales = icu::Locale::getAvailableLocales(num_locales);
35   assert(num_locales > 0);
36   return locales[(*rng)() % num_locales];
37 }
38 
UnicodeStringFromUtf8(const uint8_t * data,size_t size)39 icu::UnicodeString UnicodeStringFromUtf8(const uint8_t* data, size_t size) {
40   return icu::UnicodeString::fromUTF8(
41       icu::StringPiece(reinterpret_cast<const char*>(data), size));
42 }
43 
UnicodeStringFromUtf32(const uint8_t * data,size_t size)44 icu::UnicodeString UnicodeStringFromUtf32(const uint8_t* data, size_t size) {
45   std::vector<UChar32> uchars;
46   uchars.resize(size * sizeof(uint8_t) / (sizeof(UChar32)));
47   memcpy(uchars.data(), data, uchars.size() * sizeof(UChar32));
48   for (size_t i = 0; i < uchars.size(); ++i) {
49     // The valid range for UTF32 is [0, UCHAR_MAX_VALUE]
50     // By  % with (UCHAR_MAX_VALUE + 2) we make the output mostly valid  with
51     // a small percentage of (1 / UCHAR_MAX_VALUE) invalid data in UTF8.
52     uchars[i] = uchars[i] % (UCHAR_MAX_VALUE + 2);
53   }
54 
55   return icu::UnicodeString::fromUTF32(uchars.data(), uchars.size());
56 }
57 
RandomChar16Array(size_t random_value,const uint8_t * data,size_t size)58 std::vector<char16_t> RandomChar16Array(size_t random_value,
59                                         const uint8_t* data,
60                                         size_t size) {
61   std::vector<char16_t> arr;
62   arr.resize(random_value % size * sizeof(uint8_t) / sizeof(char16_t));
63   memcpy(arr.data(), data, arr.size() * sizeof(char16_t) / sizeof(uint8_t));
64   return arr;
65 }
66 
67 #endif  // THIRD_PARTY_ICU_FUZZERS_FUZZER_UTILS_H_
68