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