v8/test/fuzzer/regexp.cc
ahaas 2ba24a71b6 [regexp fuzzer] Let the fuzzer input select the regexp flag.
With this CL the regexp-parser-fuzzer uses the first byte of the fuzzer
input to select the regexp flag instead of executing each input with all
possible flags. Thereby the fuzzer can explore more inputs and with its
coverage metric will explore all flags only for interesting inputs.

I updated all files in test/fuzzer/regexp and added a random byte at the beginning. This byte is used by the fuzzer to determine the flag.

BUG=chromium:664436
R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2511373002
Cr-Commit-Position: refs/heads/master@{#41176}
2016-11-22 12:59:38 +00:00

81 lines
3.0 KiB
C++

// 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 <limits.h>
#include <stddef.h>
#include <stdint.h>
#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;
void Test(v8::Isolate* isolate, i::Handle<i::JSRegExp> regexp,
i::Handle<i::String> subject,
i::Handle<i::RegExpMatchInfo> results_array) {
v8::TryCatch try_catch(isolate);
USE(i::RegExpImpl::Exec(regexp, subject, 0, results_array));
}
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_regexp_lookbehind = true;
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Factory* factory = i_isolate->factory();
if (size > INT_MAX) return 0;
i::MaybeHandle<i::String> maybe_source = factory->NewStringFromOneByte(
i::Vector<const uint8_t>(data, static_cast<int>(size)));
i::Handle<i::String> 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<i::RegExpMatchInfo> results_array = factory->NewRegExpMatchInfo();
i::Handle<i::String> one_byte =
factory->NewStringFromOneByte(i::Vector<const uint8_t>(one_byte_array, 6))
.ToHandleChecked();
i::Handle<i::String> two_byte =
factory->NewStringFromTwoByte(i::Vector<const i::uc16>(two_byte_array, 6))
.ToHandleChecked();
i::Handle<i::JSRegExp> regexp;
{
v8::TryCatch try_catch(isolate);
// Create a string so that we can calculate a hash from the input data.
std::string str = std::string(reinterpret_cast<const char*>(data), size);
i::JSRegExp::Flags flag = static_cast<i::JSRegExp::Flags>(
std::hash<std::string>()(str) % (kAllFlags + 1));
i::MaybeHandle<i::JSRegExp> maybe_regexp = i::JSRegExp::New(source, flag);
if (!maybe_regexp.ToHandle(&regexp)) {
i_isolate->clear_pending_exception();
return 0;
}
}
Test(isolate, regexp, one_byte, results_array);
Test(isolate, regexp, two_byte, results_array);
Test(isolate, regexp, factory->empty_string(), results_array);
Test(isolate, regexp, source, results_array);
isolate->RequestGarbageCollectionForTesting(
v8::Isolate::kFullGarbageCollection);
return 0;
}