v8/test/fuzzer/parser.cc
Leszek Swirski 313d4844d9 Reland^3 "[parser] Introduce UnoptimizedCompileFlags"
This is a reland of 0a59e0cb08
which was a reland of 146f5375da
which was a reland of d91679bf3a

Initializes the BackgroundCompileTasks's language_mode in the
constructor (previously only initialized after successful parse) in case
the parse failed. We still need to reset it after parse in case the
language mode changed (because we encountered "use strict").

Original change's description:
> [parser] Introduce UnoptimizedCompileFlags
>
> UnoptimizedCompileFlags defines the input flags shared between parse and
> compile (currently parse-only). It is set initially with some values, and
> is immutable after being passed to ParseInfo (ParseInfo still has getters
> for the fields, but no setters).
>
> Since a few of the existing flags were output flags, ParseInfo now has a
> new output_flags field, which will eventually migrate to a ParseOutputs
> structure.
>
> Bug: v8:10314
> Change-Id: If3890a5fad883bca80a97bf9dfe44d91797dc286
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2096580
> Commit-Queue: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Simon Zünd <szuend@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#66782}

TBR=ulan@chromium.org,szuend@chromium.org,rmcilroy@chromium.org

Bug: v8:10314
Change-Id: Ieee0bbfade4fe0b56de03bff47a7364959608d6a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157367
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67265}
2020-04-21 08:13:23 +00:00

94 lines
2.9 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 <cctype>
#include <list>
#include "include/v8.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parsing.h"
#include "src/parsing/preparser.h"
#include "test/fuzzer/fuzzer-support.h"
bool IsValidInput(const uint8_t* data, size_t size) {
// Ignore too long inputs as they tend to find OOM or timeouts, not real bugs.
if (size > 2048) return false;
std::vector<char> parentheses;
const char* ptr = reinterpret_cast<const char*>(data);
for (size_t i = 0; i != size; ++i) {
// Check that all characters in the data are valid.
if (!std::isspace(ptr[i]) && !std::isprint(ptr[i])) return false;
// Check balance of parentheses in the data.
switch (ptr[i]) {
case '(':
case '[':
case '{':
parentheses.push_back(ptr[i]);
break;
case ')':
if (parentheses.empty() || parentheses.back() != '(') return false;
parentheses.pop_back();
break;
case ']':
if (parentheses.empty() || parentheses.back() != '[') return false;
parentheses.pop_back();
break;
case '}':
if (parentheses.empty() || parentheses.back() != '{') return false;
parentheses.pop_back();
break;
default:
break;
}
}
return parentheses.empty();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (!IsValidInput(data, size)) {
return 0;
}
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);
v8::internal::Isolate* i_isolate =
reinterpret_cast<v8::internal::Isolate*>(isolate);
v8::internal::Factory* factory = i_isolate->factory();
if (size > INT_MAX) return 0;
v8::internal::MaybeHandle<v8::internal::String> source =
factory->NewStringFromOneByte(
v8::internal::Vector<const uint8_t>(data, static_cast<int>(size)));
if (source.is_null()) return 0;
v8::internal::Handle<v8::internal::Script> script =
factory->NewScript(source.ToHandleChecked());
v8::internal::UnoptimizedCompileFlags flags =
v8::internal::UnoptimizedCompileFlags::ForScriptCompile(i_isolate,
*script);
v8::internal::ParseInfo info(i_isolate, flags);
if (!v8::internal::parsing::ParseProgram(&info, script, i_isolate)) {
i_isolate->OptionalRescheduleException(true);
}
isolate->RequestGarbageCollectionForTesting(
v8::Isolate::kFullGarbageCollection);
return 0;
}