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 #elif defined(__Fuchsia__)
29 #include <limits.h>
30 #include <unistd.h>
31 #else // Linux
32 #include <linux/limits.h>
33 #include <unistd.h>
34 #endif // _WIN32
35
36 namespace {
37
38 // pdf_fuzzer_init.cc and pdf_fuzzer_init_public.cc are mutually exclusive
39 // and should not be built together. Static initializers and destructors
40 // avoid problems with fuzzer initialization and termination.
41 PDFFuzzerInitPublic g_instance;
42
43 #ifdef PDF_ENABLE_V8
ProgramPath()44 std::string ProgramPath() {
45 std::string result;
46 #ifdef _WIN32
47 char path[MAX_PATH];
48 DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH);
49 if (len != 0)
50 result = std::string(path, len);
51 #elif defined(__APPLE__)
52 char path[PATH_MAX];
53 unsigned int len = PATH_MAX;
54 if (!_NSGetExecutablePath(path, &len)) {
55 std::unique_ptr<char, pdfium::FreeDeleter> resolved_path(
56 realpath(path, nullptr));
57 if (resolved_path.get())
58 result = std::string(resolved_path.get());
59 }
60 #else // Linux
61 char path[PATH_MAX];
62 ssize_t len = readlink("/proc/self/exe", path, PATH_MAX);
63 if (len > 0)
64 result = std::string(path, len);
65 #endif
66 return result;
67 }
68 #endif // PDF_ENABLE_V8
69
70 } // namespace
71
PDFFuzzerInitPublic()72 PDFFuzzerInitPublic::PDFFuzzerInitPublic() {
73 #ifdef PDF_ENABLE_V8
74 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
75 platform_ = InitializeV8ForPDFiumWithStartupData(
76 ProgramPath(), std::string(), std::string(), &snapshot_blob_);
77 #else // V8_USE_EXTERNAL_STARTUP_DATA
78 platform_ = InitializeV8ForPDFium(ProgramPath(), std::string());
79 #endif // V8_USE_EXTERNAL_STARTUP_DATA
80 #ifdef PDF_ENABLE_XFA
81 allocator_.reset(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
82 v8::Isolate::CreateParams create_params;
83 create_params.array_buffer_allocator = allocator_.get();
84 isolate_.reset(v8::Isolate::New(create_params));
85 #endif // PDF_ENABLE_XFA
86 #endif // PDF_ENABLE_V8
87 memset(&config_, '\0', sizeof(config_));
88 config_.version = 3;
89 config_.m_pUserFontPaths = nullptr;
90 config_.m_pPlatform = nullptr;
91 config_.m_pIsolate = nullptr;
92 config_.m_v8EmbedderSlot = 0;
93 #ifdef PDF_ENABLE_V8
94 config_.m_pPlatform = platform_.get();
95 config_.m_pIsolate = isolate_.get();
96 #endif // PDF_ENABLE_V8
97 FPDF_InitLibraryWithConfig(&config_);
98
99 memset(&unsupport_info_, '\0', sizeof(unsupport_info_));
100 unsupport_info_.version = 1;
101 unsupport_info_.FSDK_UnSupport_Handler = [](UNSUPPORT_INFO*, int) {};
102 FSDK_SetUnSpObjProcessHandler(&unsupport_info_);
103
104 #ifdef PDF_ENABLE_XFA
105 xfa_process_state_ =
106 std::make_unique<XFAProcessState>(platform_.get(), isolate_.get());
107 FPDF_SetFuzzerPerProcessState(xfa_process_state_.get());
108 #endif
109 }
110
~PDFFuzzerInitPublic()111 PDFFuzzerInitPublic::~PDFFuzzerInitPublic() {
112 FPDF_SetFuzzerPerProcessState(nullptr);
113 }
114