// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/task/single_thread_task_executor.h"
#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h"
#include "components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.h"
#include "mojo/core/embedder/embedder.h"
#include "testing/libfuzzer/libfuzzer_exports.h"
#include "testing/libfuzzer/proto/lpm_interface.h"
#include "components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.pb.h"
namespace {
struct Env {
public:
Env() {
mojo::core::Init();
// Run fuzzer with the flag --dump-to-png[=dir-name] to dump the browser
// display into PNG files for debugging purposes.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
auto png_dir_path =
command_line->HasSwitch("dump-to-png")
? std::optional<base::FilePath>(
command_line->GetSwitchValuePath("dump-to-png"))
: std::nullopt;
// Re-initialize logging in order to pick up any command-line parameters
// (such as --v=1 to enable verbose logging).
logging::LoggingSettings settings;
settings.logging_dest =
logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
logging::InitLogging(settings);
browser_process = std::make_unique<viz::FuzzerBrowserProcess>(png_dir_path);
}
~Env() = default;
std::unique_ptr<viz::FuzzerBrowserProcess> browser_process;
private:
base::SingleThreadTaskExecutor single_thread_task_executor_;
// Instantiation needed to make histogram macros in the SubmitCompositorFrame
// flow work when verbosity is on.
base::AtExitManager exit_manager_;
};
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
base::CommandLine::Init(*argc, *argv);
return 0;
}
DEFINE_BINARY_PROTO_FUZZER(
const viz::proto::CompositorRenderPass& render_pass_spec) {
static base::NoDestructor<Env> env;
viz::FuzzedData fuzzed_frame =
viz::BuildFuzzedCompositorFrame(render_pass_spec);
env->browser_process->EmbedFuzzedCompositorFrame(
std::move(fuzzed_frame.frame), std::move(fuzzed_frame.allocated_bitmaps));
}