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