| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Copyright 2016 The RE2 Authors. All Rights Reserved. | |
| 6 // Use of this source code is governed by a BSD-style | |
| 7 // license that can be found in the LICENSE file. | |
| 8 | |
| 9 #include <stddef.h> | |
| 10 #include <stdint.h> | |
| 11 | |
| 12 #include <map> | |
| 13 #include <string> | |
| 14 | |
| 15 #include "re2/re2.h" | |
| 16 | |
| 17 using re2::StringPiece; | |
| 18 using std::string; | |
| 19 | |
| 20 // NOT static, NOT signed. | |
| 21 uint8_t dummy = 0; | |
| 22 | |
| 23 void Test(StringPiece pattern, const RE2::Options& options, StringPiece text) { | |
| 24 RE2 re(pattern, options); | |
| 25 if (!re.ok()) | |
| 26 return; | |
| 27 | |
| 28 // Don't waste time fuzzing high-fanout programs. | |
| 29 // (They can also cause bug reports due to fuzzer timeouts.) | |
| 30 std::map<int, int> histogram; | |
| 31 int fanout = re.ProgramFanout(&histogram); | |
| 32 if (fanout > 9) | |
| 33 return; | |
| 34 | |
| 35 StringPiece sp1, sp2, sp3, sp4; | |
| 36 string s1, s2, s3, s4; | |
| 37 int i1, i2, i3, i4; | |
| 38 double d1, d2, d3, d4; | |
| 39 | |
| 40 RE2::FullMatch(text, re, &sp1, &sp2, &sp3, &sp4); | |
| 41 RE2::PartialMatch(text, re, &s1, &s2, &s3, &s4); | |
| 42 | |
| 43 sp1 = sp2 = text; | |
| 44 RE2::Consume(&sp1, re, &i1, &i2, &i3, &i4); | |
| 45 RE2::FindAndConsume(&sp2, re, &d1, &d2, &d3, &d4); | |
| 46 | |
| 47 s3 = s4 = text.ToString(); | |
| 48 RE2::Replace(&s3, re, ""); | |
| 49 RE2::GlobalReplace(&s4, re, ""); | |
| 50 | |
| 51 // Exercise some other API functionality. | |
| 52 dummy += re.NumberOfCapturingGroups(); | |
| 53 dummy += RE2::QuoteMeta(pattern).size(); | |
| 54 } | |
| 55 | |
| 56 // Entry point for libFuzzer. | |
| 57 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | |
| 58 if (size == 0 || size > 1024) | |
| 59 return 0; | |
| 60 | |
| 61 // The one-at-a-time hash by Bob Jenkins. | |
| 62 uint32_t hash = 0; | |
| 63 for (size_t i = 0; i < size; i++) { | |
| 64 hash += data[i]; | |
| 65 hash += (hash << 10); | |
| 66 hash ^= (hash >> 6); | |
| 67 } | |
| 68 hash += (hash << 3); | |
| 69 hash ^= (hash >> 11); | |
| 70 hash += (hash << 15); | |
| 71 | |
| 72 RE2::Options options; | |
| 73 options.set_log_errors(false); | |
| 74 options.set_encoding(hash & 1 ? RE2::Options::EncodingLatin1 | |
| 75 : RE2::Options::EncodingUTF8); | |
| 76 options.set_posix_syntax(hash & 2); | |
| 77 options.set_longest_match(hash & 4); | |
| 78 options.set_literal(hash & 8); | |
| 79 options.set_never_nl(hash & 16); | |
| 80 options.set_dot_nl(hash & 32); | |
| 81 options.set_never_capture(hash & 64); | |
| 82 options.set_case_sensitive(hash & 128); | |
| 83 options.set_perl_classes(hash & 256); | |
| 84 options.set_word_boundary(hash & 512); | |
| 85 options.set_one_line(hash & 1024); | |
| 86 | |
| 87 const char* ptr = reinterpret_cast<const char*>(data); | |
| 88 int len = static_cast<int>(size); | |
| 89 | |
| 90 StringPiece pattern(ptr, len); | |
| 91 StringPiece text(ptr, len); | |
| 92 Test(pattern, options, text); | |
| 93 | |
| 94 for (int i = 2; i <= 4; i++) { | |
| 95 if (len < i) | |
| 96 break; | |
| 97 | |
| 98 int frac = len / i; | |
| 99 pattern = StringPiece(ptr, frac); | |
| 100 text = StringPiece(ptr + frac, len - frac); | |
| 101 Test(pattern, options, text); | |
| 102 } | |
| 103 | |
| 104 return 0; | |
| 105 } | |
| OLD | NEW |