Line data Source code
1 : // Copyright 2016 the V8 project 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 : #include <limits.h>
6 : #include <stddef.h>
7 : #include <stdint.h>
8 :
9 : #include "include/v8.h"
10 : #include "src/factory.h"
11 : #include "src/objects-inl.h"
12 : #include "src/objects.h"
13 : #include "src/regexp/jsregexp.h"
14 : #include "test/fuzzer/fuzzer-support.h"
15 :
16 : namespace i = v8::internal;
17 :
18 80 : void Test(v8::Isolate* isolate, i::Handle<i::JSRegExp> regexp,
19 : i::Handle<i::String> subject,
20 : i::Handle<i::RegExpMatchInfo> results_array) {
21 80 : v8::TryCatch try_catch(isolate);
22 160 : if (i::RegExpImpl::Exec(regexp, subject, 0, results_array).is_null()) {
23 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
24 0 : i_isolate->OptionalRescheduleException(true);
25 80 : }
26 80 : }
27 :
28 25 : extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
29 25 : v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
30 25 : v8::Isolate* isolate = support->GetIsolate();
31 :
32 : v8::Isolate::Scope isolate_scope(isolate);
33 50 : v8::HandleScope handle_scope(isolate);
34 25 : v8::Context::Scope context_scope(support->GetContext());
35 50 : v8::TryCatch try_catch(isolate);
36 :
37 25 : i::FLAG_harmony_regexp_lookbehind = true;
38 :
39 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
40 : i::Factory* factory = i_isolate->factory();
41 :
42 25 : CHECK(!i_isolate->has_pending_exception());
43 25 : if (size > INT_MAX) return 0;
44 : i::MaybeHandle<i::String> maybe_source = factory->NewStringFromOneByte(
45 50 : i::Vector<const uint8_t>(data, static_cast<int>(size)));
46 : i::Handle<i::String> source;
47 25 : if (!maybe_source.ToHandle(&source)) {
48 : i_isolate->clear_pending_exception();
49 0 : return 0;
50 : }
51 :
52 : static const int kAllFlags = i::JSRegExp::kGlobal | i::JSRegExp::kIgnoreCase |
53 : i::JSRegExp::kMultiline | i::JSRegExp::kSticky |
54 25 : i::JSRegExp::kUnicode;
55 :
56 25 : const uint8_t one_byte_array[6] = {'f', 'o', 'o', 'b', 'a', 'r'};
57 25 : const i::uc16 two_byte_array[6] = {'f', 0xD83D, 0xDCA9, 'b', 'a', 0x2603};
58 :
59 25 : CHECK(!i_isolate->has_pending_exception());
60 25 : i::Handle<i::RegExpMatchInfo> results_array = factory->NewRegExpMatchInfo();
61 : i::Handle<i::String> one_byte =
62 25 : factory->NewStringFromOneByte(i::Vector<const uint8_t>(one_byte_array, 6))
63 50 : .ToHandleChecked();
64 : i::Handle<i::String> two_byte =
65 25 : factory->NewStringFromTwoByte(i::Vector<const i::uc16>(two_byte_array, 6))
66 50 : .ToHandleChecked();
67 :
68 : i::Handle<i::JSRegExp> regexp;
69 : {
70 25 : CHECK(!i_isolate->has_pending_exception());
71 25 : v8::TryCatch try_catch(isolate);
72 : // Create a string so that we can calculate a hash from the input data.
73 25 : std::string str = std::string(reinterpret_cast<const char*>(data), size);
74 : i::JSRegExp::Flags flag = static_cast<i::JSRegExp::Flags>(
75 25 : std::hash<std::string>()(str) % (kAllFlags + 1));
76 25 : i::MaybeHandle<i::JSRegExp> maybe_regexp = i::JSRegExp::New(source, flag);
77 25 : if (!maybe_regexp.ToHandle(®exp)) {
78 : i_isolate->clear_pending_exception();
79 : return 0;
80 20 : }
81 : }
82 20 : Test(isolate, regexp, one_byte, results_array);
83 20 : Test(isolate, regexp, two_byte, results_array);
84 20 : Test(isolate, regexp, factory->empty_string(), results_array);
85 20 : Test(isolate, regexp, source, results_array);
86 : isolate->RequestGarbageCollectionForTesting(
87 20 : v8::Isolate::kFullGarbageCollection);
88 20 : CHECK(!i_isolate->has_pending_exception());
89 : return 0;
90 : }
|