• 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 <array>
5 #include <cstring>
6 
7 #include "fuzzer_utils.h"
8 #include "unicode/coll.h"
9 #include "unicode/localpointer.h"
10 #include "unicode/locid.h"
11 
12 IcuEnvironment* env = new IcuEnvironment();
13 
14 static const std::array<icu::Collator::ECollationStrength, 5> kStrength = {
15     icu::Collator::PRIMARY,
16     icu::Collator::SECONDARY,
17     icu::Collator::TERTIARY,
18     icu::Collator::QUATERNARY,
19     icu::Collator::IDENTICAL
20 };
21 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)22 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
23   UErrorCode status = U_ZERO_ERROR;
24 
25   uint16_t rnd16;
26 
27   if (size < 2 + sizeof(rnd16))
28     return 0;
29 
30   std::memcpy(&rnd16, data, sizeof(rnd16));
31   size -= sizeof(rnd16);
32   data += sizeof(rnd16);
33   icu::Collator::ECollationStrength strength = kStrength[rnd16 % kStrength.size()];
34   const icu::Locale& locale = GetRandomLocale(rnd16 / kStrength.size());
35 
36   // Limit the comparison size to 4096 to avoid unnecessary timeout
37   if (size > 4096) {
38       size = 4096;
39   }
40   std::unique_ptr<char16_t[]> compbuff1(new char16_t[size/4]);
41   std::memcpy(compbuff1.get(), data, (size/4)*2);
42   std::unique_ptr<char16_t[]> compbuff2(new char16_t[size/4]);
43   std::memcpy(compbuff2.get(), data + size/2, (size/4)*2);
44 
45 
46   icu::LocalPointer<icu::Collator> fuzzCollator(
47       icu::Collator::createInstance(locale, status), status);
48   if (U_SUCCESS(status)) {
49 
50     fuzzCollator->setStrength(strength);
51 
52     fuzzCollator->compare(compbuff1.get(), size/4,
53                           compbuff2.get(), size/4);
54   }
55   status = U_ZERO_ERROR;
56 
57   std::string str(reinterpret_cast<const char*>(data), size);
58   fuzzCollator.adoptInstead(
59       icu::Collator::createInstance(icu::Locale(str.c_str()), status));
60   return 0;
61 }
62