blob: 6790461968517e999d48e71fe0f1cf6a4e65dc76 [file] [log] [blame]
Marja Hölttäd9292152017-10-18 11:38:051// Copyright 2017 The Chromium 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
Jonathan Metzman71c8f842017-11-13 22:03:325#include <stdlib.h>
6
7#include <iostream>
8
Avi Drissmandbd6ce12019-04-05 20:06:379#include "javascript_parser.pb.h" // from out/gen
Marja Hölttäd9292152017-10-18 11:38:0510#include "testing/libfuzzer/fuzzers/javascript_parser_proto_to_string.h"
11#include "third_party/libprotobuf-mutator/src/src/libfuzzer/libfuzzer_macro.h"
12
13#include "v8/include/libplatform/libplatform.h"
14#include "v8/include/v8.h"
15
16// Silence logging from the protobuf library.
17protobuf_mutator::protobuf::LogSilencer log_silencer;
18
19v8::Isolate* isolate = nullptr;
20
21std::string protobuf_to_string(
22 const javascript_parser_proto_fuzzer::Source& source_protobuf) {
23 std::string source;
24 for (const auto& token : source_protobuf.tokens()) {
Jonathan Metzman33d19422017-10-19 14:57:1025 source += token_to_string(token, 0) + std::string(" ");
Marja Hölttäd9292152017-10-18 11:38:0526 }
27 return source;
28}
29
Max Moroz80ee67f42018-05-08 17:15:2630// Explicitly specify some attributes to avoid issues with the linker dead-
31// stripping the following function on macOS, as it is not called directly
32// by fuzz target. LibFuzzer runtime uses dlsym() to resolve that function.
Benoit Lize0d7e28a2022-03-10 19:08:4033#if V8_OS_MACOS
Max Moroz80ee67f42018-05-08 17:15:2634__attribute__((used)) __attribute__((visibility("default")))
Benoit Lize0d7e28a2022-03-10 19:08:4035#endif // V8_OS_MACOS
Max Moroz80ee67f42018-05-08 17:15:2636extern "C" int
37LLVMFuzzerInitialize(int* argc, char*** argv) {
Marja Hölttäd9292152017-10-18 11:38:0538 v8::V8::InitializeICUDefaultLocation((*argv)[0]);
39 v8::V8::InitializeExternalStartupData((*argv)[0]);
Marja Hölttä5bfe9332017-10-19 14:51:3440 v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
Marja Hölttäd9292152017-10-18 11:38:0541
Dan Elphickcf615622018-12-21 16:16:4042 // Intentionally leaked during fuzzing.
43 v8::Platform* platform = v8::platform::NewDefaultPlatform().release();
Marja Hölttäd9292152017-10-18 11:38:0544 v8::V8::InitializePlatform(platform);
45 v8::V8::Initialize();
46
47 v8::Isolate::CreateParams create_params;
48 create_params.array_buffer_allocator =
49 v8::ArrayBuffer::Allocator::NewDefaultAllocator();
50 isolate = v8::Isolate::New(create_params);
51 return 0;
52}
53
54DEFINE_BINARY_PROTO_FUZZER(
55 const javascript_parser_proto_fuzzer::Source& source_protobuf) {
56 v8::Isolate::Scope isolate_scope(isolate);
57 v8::HandleScope handle_scope(isolate);
58 v8::Local<v8::Context> context = v8::Context::New(isolate);
59 v8::Context::Scope context_scope(context);
60
61 std::string source_string = protobuf_to_string(source_protobuf);
Jonathan Metzman71c8f842017-11-13 22:03:3262
Marja Hölttäcc4e3912017-11-24 00:04:3463 if (getenv("LPM_DUMP_NATIVE_INPUT")) {
Jonathan Metzman71c8f842017-11-13 22:03:3264 std::cout << source_string << std::endl;
Marja Hölttäcc4e3912017-11-24 00:04:3465 std::cout << "module: " << source_protobuf.is_module() << std::endl;
66 }
Marja Hölttä5bfe9332017-10-19 14:51:3467 v8::Local<v8::String> source_v8_string =
Marja Hölttäd9292152017-10-18 11:38:0568 v8::String::NewFromUtf8(isolate, source_string.c_str(),
69 v8::NewStringType::kNormal)
70 .ToLocalChecked();
71
72 {
73 v8::TryCatch try_catch(isolate);
74
Marja Hölttä5bfe9332017-10-19 14:51:3475 if (source_protobuf.is_module()) {
76 v8::Local<v8::String> name =
77 v8::String::NewFromUtf8(isolate, "module.js",
78 v8::NewStringType::kNormal)
79 .ToLocalChecked();
80
Maya Lekova2a610dd2021-03-04 14:51:3881 v8::ScriptOrigin origin(isolate, name, 0, 0, false, -1,
82 v8::Local<v8::Value>(), false, false, true);
Marja Hölttä5bfe9332017-10-19 14:51:3483 v8::ScriptCompiler::Source source(source_v8_string, origin);
84 v8::MaybeLocal<v8::Module> module =
85 v8::ScriptCompiler::CompileModule(isolate, &source);
86 // TODO(marja): Figure out a more elegant way to silence the warning.
87 module.IsEmpty();
88 } else {
89 v8::MaybeLocal<v8::Script> script =
90 v8::Script::Compile(context, source_v8_string);
91 // TODO(marja): Figure out a more elegant way to silence the warning.
92 script.IsEmpty();
93 }
Marja Hölttäd9292152017-10-18 11:38:0594
95 // TODO(crbug.com/775796): run the code once we find a way to avoid endless
96 // loops.
97 }
98}