From 9f5dca8faa05d70b89ad9b795b0feed1513615aa Mon Sep 17 00:00:00 2001 From: yangguo Date: Mon, 1 Feb 2016 06:00:12 -0800 Subject: [PATCH] [regexp] add fuzzer support for regexp parser and compiler. R=jochen@chromium.org BUG=chromium:577261 LOG=N Review URL: https://codereview.chromium.org/1655853002 Cr-Commit-Position: refs/heads/master@{#33640} --- BUILD.gn | 18 +++++++++++ test/fuzzer/fuzzer.gyp | 27 ++++++++++++++++ test/fuzzer/fuzzer.isolate | 2 ++ test/fuzzer/regexp.cc | 64 ++++++++++++++++++++++++++++++++++++++ test/fuzzer/regexp/test00 | 1 + test/fuzzer/regexp/test01 | 1 + test/fuzzer/regexp/test02 | 1 + test/fuzzer/regexp/test03 | 1 + test/fuzzer/regexp/test04 | 1 + test/fuzzer/regexp/test05 | 1 + test/fuzzer/regexp/test06 | 1 + test/fuzzer/regexp/test07 | 1 + test/fuzzer/regexp/test08 | 1 + test/fuzzer/regexp/test09 | 1 + test/fuzzer/regexp/test10 | 1 + test/fuzzer/regexp/test11 | 1 + test/fuzzer/regexp/test12 | 1 + test/fuzzer/regexp/test13 | 1 + test/fuzzer/regexp/test14 | 1 + test/fuzzer/regexp/test15 | 1 + test/fuzzer/regexp/test16 | 1 + test/fuzzer/regexp/test17 | 1 + test/fuzzer/regexp/test18 | 1 + test/fuzzer/regexp/test19 | 1 + test/fuzzer/regexp/test20 | 1 + test/fuzzer/regexp/test21 | 1 + test/fuzzer/regexp/test22 | 1 + test/fuzzer/regexp/test23 | 1 + test/fuzzer/regexp/test24 | 1 + test/fuzzer/testcfg.py | 2 +- 30 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 test/fuzzer/regexp.cc create mode 100644 test/fuzzer/regexp/test00 create mode 100644 test/fuzzer/regexp/test01 create mode 100644 test/fuzzer/regexp/test02 create mode 100644 test/fuzzer/regexp/test03 create mode 100644 test/fuzzer/regexp/test04 create mode 100644 test/fuzzer/regexp/test05 create mode 100644 test/fuzzer/regexp/test06 create mode 100644 test/fuzzer/regexp/test07 create mode 100644 test/fuzzer/regexp/test08 create mode 100644 test/fuzzer/regexp/test09 create mode 100644 test/fuzzer/regexp/test10 create mode 100644 test/fuzzer/regexp/test11 create mode 100644 test/fuzzer/regexp/test12 create mode 100644 test/fuzzer/regexp/test13 create mode 100644 test/fuzzer/regexp/test14 create mode 100644 test/fuzzer/regexp/test15 create mode 100644 test/fuzzer/regexp/test16 create mode 100644 test/fuzzer/regexp/test17 create mode 100644 test/fuzzer/regexp/test18 create mode 100644 test/fuzzer/regexp/test19 create mode 100644 test/fuzzer/regexp/test20 create mode 100644 test/fuzzer/regexp/test21 create mode 100644 test/fuzzer/regexp/test22 create mode 100644 test/fuzzer/regexp/test23 create mode 100644 test/fuzzer/regexp/test24 diff --git a/BUILD.gn b/BUILD.gn index 3f247ae587..eef2f19702 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1953,3 +1953,21 @@ source_set("parser_fuzzer") { ":toolchain", ] } + +source_set("regexp_fuzzer") { + sources = [ + "test/fuzzer/regexp.cc", + ] + + deps = [ + ":fuzzer_support", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + configs += [ + ":internal_config", + ":features", + ":toolchain", + ] +} diff --git a/test/fuzzer/fuzzer.gyp b/test/fuzzer/fuzzer.gyp index 38ed563cda..740a920810 100644 --- a/test/fuzzer/fuzzer.gyp +++ b/test/fuzzer/fuzzer.gyp @@ -34,6 +34,32 @@ 'parser.cc', ], }, + { + 'target_name': 'regexp_fuzzer', + 'type': 'executable', + 'dependencies': [ + 'regexp_fuzzer_lib', + ], + 'include_dirs': [ + '../..', + ], + 'sources': [ + 'fuzzer.cc', + ], + }, + { + 'target_name': 'regexp_fuzzer_lib', + 'type': 'static_library', + 'dependencies': [ + 'fuzzer_support', + ], + 'include_dirs': [ + '../..', + ], + 'sources': [ ### gcmole(all) ### + 'regexp.cc', + ], + }, { 'target_name': 'fuzzer_support', 'type': 'static_library', @@ -66,6 +92,7 @@ 'type': 'none', 'dependencies': [ 'parser_fuzzer', + 'regexp_fuzzer', ], 'includes': [ '../../build/isolate.gypi', diff --git a/test/fuzzer/fuzzer.isolate b/test/fuzzer/fuzzer.isolate index 1a3a6a3598..e03ab9bfe7 100644 --- a/test/fuzzer/fuzzer.isolate +++ b/test/fuzzer/fuzzer.isolate @@ -6,9 +6,11 @@ 'variables': { 'files': [ '<(PRODUCT_DIR)/parser_fuzzer<(EXECUTABLE_SUFFIX)', + '<(PRODUCT_DIR)/regexp_fuzzer<(EXECUTABLE_SUFFIX)', './fuzzer.status', './testcfg.py', './parser/', + './regexp/', ], }, 'includes': [ diff --git a/test/fuzzer/regexp.cc b/test/fuzzer/regexp.cc new file mode 100644 index 0000000000..f5ba5c9ea9 --- /dev/null +++ b/test/fuzzer/regexp.cc @@ -0,0 +1,64 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include "include/v8.h" +#include "src/factory.h" +#include "src/objects-inl.h" +#include "src/objects.h" +#include "src/regexp/jsregexp.h" +#include "test/fuzzer/fuzzer-support.h" + +namespace i = v8::internal; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get(); + v8::Isolate* isolate = support->GetIsolate(); + + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + v8::Context::Scope context_scope(support->GetContext()); + v8::TryCatch try_catch(isolate); + + i::FLAG_harmony_unicode_regexps = true; + i::FLAG_harmony_regexp_lookbehind = true; + + i::Isolate* i_isolate = reinterpret_cast(isolate); + i::Factory* factory = i_isolate->factory(); + + if (size > INT_MAX) return 0; + i::MaybeHandle maybe_source = factory->NewStringFromOneByte( + i::Vector(data, static_cast(size))); + i::Handle source; + if (!maybe_source.ToHandle(&source)) return 0; + + static const int kAllFlags = i::JSRegExp::kGlobal | i::JSRegExp::kIgnoreCase | + i::JSRegExp::kMultiline | i::JSRegExp::kSticky | + i::JSRegExp::kUnicode; + + const uint8_t one_byte_array[6] = {'f', 'o', 'o', 'b', 'a', 'r'}; + const i::uc16 two_byte_array[6] = {'f', 0xD83D, 0xDCA9, 'b', 'a', 0x2603}; + + i::Handle results_array = factory->NewJSArray(4); + i::Handle one_byte = + factory->NewStringFromOneByte(i::Vector(one_byte_array, 6)) + .ToHandleChecked(); + i::Handle two_byte = + factory->NewStringFromTwoByte(i::Vector(two_byte_array, 6)) + .ToHandleChecked(); + + for (int flags = 0; flags <= kAllFlags; flags++) { + v8::TryCatch try_catch(isolate); + i::MaybeHandle maybe_regexp = + i::JSRegExp::New(source, static_cast(flags)); + i::Handle regexp; + if (!maybe_regexp.ToHandle(®exp)) continue; + USE(i::RegExpImpl::Exec(regexp, one_byte, 0, results_array).is_null() && + i::RegExpImpl::Exec(regexp, two_byte, 0, results_array).is_null()); + } + + return 0; +} diff --git a/test/fuzzer/regexp/test00 b/test/fuzzer/regexp/test00 new file mode 100644 index 0000000000..d2a71aece8 --- /dev/null +++ b/test/fuzzer/regexp/test00 @@ -0,0 +1 @@ +a* diff --git a/test/fuzzer/regexp/test01 b/test/fuzzer/regexp/test01 new file mode 100644 index 0000000000..83877e955f --- /dev/null +++ b/test/fuzzer/regexp/test01 @@ -0,0 +1 @@ +xyz{93}? diff --git a/test/fuzzer/regexp/test02 b/test/fuzzer/regexp/test02 new file mode 100644 index 0000000000..d27d2ce6ba --- /dev/null +++ b/test/fuzzer/regexp/test02 @@ -0,0 +1 @@ +(foo|bar|baz) diff --git a/test/fuzzer/regexp/test03 b/test/fuzzer/regexp/test03 new file mode 100644 index 0000000000..da14770d64 --- /dev/null +++ b/test/fuzzer/regexp/test03 @@ -0,0 +1 @@ +[^] diff --git a/test/fuzzer/regexp/test04 b/test/fuzzer/regexp/test04 new file mode 100644 index 0000000000..a672b260b0 --- /dev/null +++ b/test/fuzzer/regexp/test04 @@ -0,0 +1 @@ +[\d] diff --git a/test/fuzzer/regexp/test05 b/test/fuzzer/regexp/test05 new file mode 100644 index 0000000000..edcff4e452 --- /dev/null +++ b/test/fuzzer/regexp/test05 @@ -0,0 +1 @@ +\c1 diff --git a/test/fuzzer/regexp/test06 b/test/fuzzer/regexp/test06 new file mode 100644 index 0000000000..74c75c65b0 --- /dev/null +++ b/test/fuzzer/regexp/test06 @@ -0,0 +1 @@ +[a\]c] diff --git a/test/fuzzer/regexp/test07 b/test/fuzzer/regexp/test07 new file mode 100644 index 0000000000..2ed8704014 --- /dev/null +++ b/test/fuzzer/regexp/test07 @@ -0,0 +1 @@ +\00011 diff --git a/test/fuzzer/regexp/test08 b/test/fuzzer/regexp/test08 new file mode 100644 index 0000000000..62d553ccfe --- /dev/null +++ b/test/fuzzer/regexp/test08 @@ -0,0 +1 @@ +(x)(x)(x)\2* diff --git a/test/fuzzer/regexp/test09 b/test/fuzzer/regexp/test09 new file mode 100644 index 0000000000..291650041b --- /dev/null +++ b/test/fuzzer/regexp/test09 @@ -0,0 +1 @@ +(?=a)?a diff --git a/test/fuzzer/regexp/test10 b/test/fuzzer/regexp/test10 new file mode 100644 index 0000000000..8aac6957c3 --- /dev/null +++ b/test/fuzzer/regexp/test10 @@ -0,0 +1 @@ +\1\2(a(?<=\1(b\1\2))\2)\1 diff --git a/test/fuzzer/regexp/test11 b/test/fuzzer/regexp/test11 new file mode 100644 index 0000000000..f9101ec517 --- /dev/null +++ b/test/fuzzer/regexp/test11 @@ -0,0 +1 @@ +\x34 diff --git a/test/fuzzer/regexp/test12 b/test/fuzzer/regexp/test12 new file mode 100644 index 0000000000..c418bbd6f4 --- /dev/null +++ b/test/fuzzer/regexp/test12 @@ -0,0 +1 @@ +\u{12345}|\u{23456} diff --git a/test/fuzzer/regexp/test13 b/test/fuzzer/regexp/test13 new file mode 100644 index 0000000000..6e50a55528 --- /dev/null +++ b/test/fuzzer/regexp/test13 @@ -0,0 +1 @@ +^a diff --git a/test/fuzzer/regexp/test14 b/test/fuzzer/regexp/test14 new file mode 100644 index 0000000000..5020b3bd00 --- /dev/null +++ b/test/fuzzer/regexp/test14 @@ -0,0 +1 @@ +a{1,1}? diff --git a/test/fuzzer/regexp/test15 b/test/fuzzer/regexp/test15 new file mode 100644 index 0000000000..d1c4bdef9f --- /dev/null +++ b/test/fuzzer/regexp/test15 @@ -0,0 +1 @@ +a\d diff --git a/test/fuzzer/regexp/test16 b/test/fuzzer/regexp/test16 new file mode 100644 index 0000000000..c2d990e791 --- /dev/null +++ b/test/fuzzer/regexp/test16 @@ -0,0 +1 @@ +a[\q] diff --git a/test/fuzzer/regexp/test17 b/test/fuzzer/regexp/test17 new file mode 100644 index 0000000000..d62fa9dc3f --- /dev/null +++ b/test/fuzzer/regexp/test17 @@ -0,0 +1 @@ +\0 diff --git a/test/fuzzer/regexp/test18 b/test/fuzzer/regexp/test18 new file mode 100644 index 0000000000..3836c6fe54 --- /dev/null +++ b/test/fuzzer/regexp/test18 @@ -0,0 +1 @@ +a{1z} diff --git a/test/fuzzer/regexp/test19 b/test/fuzzer/regexp/test19 new file mode 100644 index 0000000000..7eafbfde9f --- /dev/null +++ b/test/fuzzer/regexp/test19 @@ -0,0 +1 @@ +{12z} diff --git a/test/fuzzer/regexp/test20 b/test/fuzzer/regexp/test20 new file mode 100644 index 0000000000..948cf947f8 --- /dev/null +++ b/test/fuzzer/regexp/test20 @@ -0,0 +1 @@ +| diff --git a/test/fuzzer/regexp/test21 b/test/fuzzer/regexp/test21 new file mode 100644 index 0000000000..5d2207be4f --- /dev/null +++ b/test/fuzzer/regexp/test21 @@ -0,0 +1 @@ +(?:ab)* diff --git a/test/fuzzer/regexp/test22 b/test/fuzzer/regexp/test22 new file mode 100644 index 0000000000..2ca04990db --- /dev/null +++ b/test/fuzzer/regexp/test22 @@ -0,0 +1 @@ +(?:a*)? diff --git a/test/fuzzer/regexp/test23 b/test/fuzzer/regexp/test23 new file mode 100644 index 0000000000..fbe9c0cd67 --- /dev/null +++ b/test/fuzzer/regexp/test23 @@ -0,0 +1 @@ +(?:a+){0} diff --git a/test/fuzzer/regexp/test24 b/test/fuzzer/regexp/test24 new file mode 100644 index 0000000000..bc09447441 --- /dev/null +++ b/test/fuzzer/regexp/test24 @@ -0,0 +1 @@ +a\Bc diff --git a/test/fuzzer/testcfg.py b/test/fuzzer/testcfg.py index 40e5e10b1d..1ea93220bd 100644 --- a/test/fuzzer/testcfg.py +++ b/test/fuzzer/testcfg.py @@ -9,7 +9,7 @@ from testrunner.objects import testcase class FuzzerTestSuite(testsuite.TestSuite): - SUB_TESTS = ( 'parser', ) + SUB_TESTS = ( 'parser', 'regexp', ) def __init__(self, name, root): super(FuzzerTestSuite, self).__init__(name, root)