1 // Copyright 2019 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "testing/fuzzers/pdf_fuzzer_init_public.h"
6
7 #include <string.h> // For memset()
8
9 #include <string>
10
11 #include "testing/fuzzers/pdfium_fuzzer_util.h"
12
13 #ifdef PDF_ENABLE_V8
14 #include "testing/free_deleter.h"
15 #include "testing/v8_initializer.h"
16 #include "v8/include/v8-platform.h"
17 #ifdef PDF_ENABLE_XFA
18 #include "testing/fuzzers/xfa_process_state.h"
19 #include "v8/include/v8-array-buffer.h"
20 #include "v8/include/v8-isolate.h"
21 #endif // PDF_ENABLE_XFA
22 #endif // PDF_ENABLE_V8
23
24 #ifdef _WIN32
25 #include <windows.h>
26 #elif defined(__APPLE__)
27 #include <mach-o/dyld.h>
28 #else // Linux
29 #include <linux/limits.h>
30 #include <unistd.h>
31 #endif // _WIN32
32
33 namespace {
34
35 // pdf_fuzzer_init.cc and pdf_fuzzer_init_public.cc are mutually exclusive
36 // and should not be built together. Static initializers and destructors
37 // avoid problems with fuzzer initialization and termination.
38 PDFFuzzerInitPublic g_instance;
39
40 #ifdef PDF_ENABLE_V8
ProgramPath()41 std::string ProgramPath() {
42 std::string result;
43 #ifdef _WIN32
44 char path[MAX_PATH];
45 DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH);
46 if (len != 0)
47 result = std::string(path, len);
48 #elif defined(__APPLE__)
49 char path[PATH_MAX];
50 unsigned int len = PATH_MAX;
51 if (!_NSGetExecutablePath(path, &len)) {
52 std::unique_ptr<char, pdfium::FreeDeleter> resolved_path(
53 realpath(path, nullptr));
54 if (resolved_path.get())
55 result = std::string(resolved_path.get());
56 }
57 #else // Linux
58 char path[PATH_MAX];
59 ssize_t len = readlink("/proc/self/exe", path, PATH_MAX);
60 if (len > 0)
61 result = std::string(path, len);
62 #endif
63 return result;
64 }
65 #endif // PDF_ENABLE_V8
66
67 } // namespace
68
PDFFuzzerInitPublic()69 PDFFuzzerInitPublic::PDFFuzzerInitPublic() {
70 #ifdef PDF_ENABLE_V8
71 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
72 platform_ = InitializeV8ForPDFiumWithStartupData(
73 ProgramPath(), std::string(), std::string(), &snapshot_blob_);
74 #else // V8_USE_EXTERNAL_STARTUP_DATA
75 platform_ = InitializeV8ForPDFium(ProgramPath(), std::string());
76 #endif // V8_USE_EXTERNAL_STARTUP_DATA
77 #ifdef PDF_ENABLE_XFA
78 allocator_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
79 v8::Isolate::CreateParams create_params;
80 create_params.array_buffer_allocator = allocator_.get();
81 isolate_.reset(v8::Isolate::New(create_params));
82 #endif // PDF_ENABLE_XFA
83 #endif // PDF_ENABLE_V8
84 memset(&config_, '\0', sizeof(config_));
85 config_.version = 4;
86 config_.m_pUserFontPaths = nullptr;
87 config_.m_pPlatform = nullptr;
88 config_.m_pIsolate = nullptr;
89 config_.m_v8EmbedderSlot = 0;
90 #ifdef PDF_ENABLE_V8
91 config_.m_pPlatform = platform_.get();
92 config_.m_pIsolate = isolate_.get();
93 #endif // PDF_ENABLE_V8
94 #if defined(PDF_USE_SKIA)
95 config_.m_RendererType = FPDF_RENDERERTYPE_SKIA;
96 #else
97 config_.m_RendererType = FPDF_RENDERERTYPE_AGG;
98 #endif
99 FPDF_InitLibraryWithConfig(&config_);
100
101 memset(&unsupport_info_, '\0', sizeof(unsupport_info_));
102 unsupport_info_.version = 1;
103 unsupport_info_.FSDK_UnSupport_Handler = [](UNSUPPORT_INFO*, int) {};
104 FSDK_SetUnSpObjProcessHandler(&unsupport_info_);
105
106 #ifdef PDF_ENABLE_XFA
107 xfa_process_state_ =
108 std::make_unique<XFAProcessState>(platform_.get(), isolate_.get());
109 FPDF_SetFuzzerPerProcessState(xfa_process_state_.get());
110 #endif
111 }
112
~PDFFuzzerInitPublic()113 PDFFuzzerInitPublic::~PDFFuzzerInitPublic() {
114 FPDF_SetFuzzerPerProcessState(nullptr);
115 }
116