313d4844d9
This is a reland of0a59e0cb08
which was a reland of146f5375da
which was a reland ofd91679bf3a
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}
94 lines
2.9 KiB
C++
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;
|
|
}
|