Split public fuzzer static initializer into its own file pdfium_fuzzer_helper.cc contained both logic for public fuzzers, and the static initalizer for setting up pdfium. So the fuzzers have a dependency on pdfium_fuzzer_helper.cc, but in component builds, they get linked into libpdfium.so. We want to avoid adding the static initializer to libpdfium.so, otherwise pdfium will get statically initialized everywhere. BUG=chromium:960288 R=thestig Change-Id: Icc93615b83ffaa0343d2a875aa7b35459bba11ef Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/54353 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
diff --git a/testing/fuzzers/BUILD.gn b/testing/fuzzers/BUILD.gn index a283927..038d2ce 100644 --- a/testing/fuzzers/BUILD.gn +++ b/testing/fuzzers/BUILD.gn
@@ -108,6 +108,7 @@ sources = invoker.sources + [ "pdfium_fuzzer_helper.cc", "pdfium_fuzzer_helper.h", + "pdf_fuzzer_init_public.cc", ] deps = [ "../:test_support",
diff --git a/testing/fuzzers/pdf_fuzzer_init.cc b/testing/fuzzers/pdf_fuzzer_init.cc index d6b10ff..954eed0 100644 --- a/testing/fuzzers/pdf_fuzzer_init.cc +++ b/testing/fuzzers/pdf_fuzzer_init.cc
@@ -19,7 +19,7 @@ FPDF_LIBRARY_CONFIG config; }; -// pdf_fuzzer_init.cc and pdfium_fuzzer_helper.cc are mutually exclusive and -// should not be built together. They deliberately have the same global +// pdf_fuzzer_init.cc and pdfium_fuzzer_init_public.cc are mutually exclusive +// and should not be built together. They deliberately have the same global // variable. static TestCase* g_test_case = new TestCase();
diff --git a/testing/fuzzers/pdf_fuzzer_init_public.cc b/testing/fuzzers/pdf_fuzzer_init_public.cc new file mode 100644 index 0000000..63bf6ae --- /dev/null +++ b/testing/fuzzers/pdf_fuzzer_init_public.cc
@@ -0,0 +1,96 @@ +// Copyright 2019 The PDFium 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 <string.h> + +#include <memory> + +#include "public/fpdf_ext.h" + +#ifdef PDF_ENABLE_V8 +#include "testing/free_deleter.h" +#include "testing/v8_initializer.h" +#include "v8/include/v8-platform.h" +#include "v8/include/v8.h" +#endif + +#ifdef _WIN32 +#include <Windows.h> +#elif defined(__APPLE__) +#include <mach-o/dyld.h> +#else // Linux +#include <unistd.h> +#endif // _WIN32 + +namespace { + +#ifdef PDF_ENABLE_V8 +std::string ProgramPath() { + std::string result; + +#ifdef _WIN32 + char path[MAX_PATH]; + DWORD len = GetModuleFileNameA(NULL, path, MAX_PATH); + if (len != 0) + result = std::string(path, len); +#elif defined(__APPLE__) + char path[PATH_MAX]; + unsigned int len = PATH_MAX; + if (!_NSGetExecutablePath(path, &len)) { + std::unique_ptr<char, pdfium::FreeDeleter> resolved_path( + realpath(path, nullptr)); + if (resolved_path.get()) + result = std::string(resolved_path.get()); + } +#else // Linux + char path[PATH_MAX]; + ssize_t len = readlink("/proc/self/exe", path, PATH_MAX); + if (len > 0) + result = std::string(path, len); +#endif + return result; +} +#endif // PDF_ENABLE_V8 + +} // namespace + +// Initialize the library once for all runs of the fuzzer. +struct TestCase { + TestCase() { +#ifdef PDF_ENABLE_V8 +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + platform = InitializeV8ForPDFiumWithStartupData( + ProgramPath(), "", &natives_blob, &snapshot_blob); +#else + platform = InitializeV8ForPDFium(ProgramPath()); +#endif // V8_USE_EXTERNAL_STARTUP_DATA +#endif // PDF_ENABLE_V8 + + memset(&config, '\0', sizeof(config)); + config.version = 2; + config.m_pUserFontPaths = nullptr; + config.m_pIsolate = nullptr; + config.m_v8EmbedderSlot = 0; + FPDF_InitLibraryWithConfig(&config); + + memset(&unsupport_info, '\0', sizeof(unsupport_info)); + unsupport_info.version = 1; + unsupport_info.FSDK_UnSupport_Handler = [](UNSUPPORT_INFO*, int) {}; + FSDK_SetUnSpObjProcessHandler(&unsupport_info); + } + +#ifdef PDF_ENABLE_V8 + std::unique_ptr<v8::Platform> platform; + v8::StartupData natives_blob; + v8::StartupData snapshot_blob; +#endif + + FPDF_LIBRARY_CONFIG config; + UNSUPPORT_INFO unsupport_info; +}; + +// pdf_fuzzer_init.cc and pdfium_fuzzer_init_public.cc are mutually exclusive +// and should not be built together. They deliberately have the same global +// variable. +static TestCase* g_test_case = new TestCase();
diff --git a/testing/fuzzers/pdfium_fuzzer_helper.cc b/testing/fuzzers/pdfium_fuzzer_helper.cc index 3861034..27e0292 100644 --- a/testing/fuzzers/pdfium_fuzzer_helper.cc +++ b/testing/fuzzers/pdfium_fuzzer_helper.cc
@@ -13,34 +13,42 @@ #include <stdlib.h> #include <string.h> -#ifdef _WIN32 -#include <Windows.h> -#elif defined(__APPLE__) -#include <mach-o/dyld.h> -#else // Linux -#include <unistd.h> -#endif // _WIN32 - #include <memory> #include <sstream> #include <string> +#include <tuple> #include <utility> #include "public/cpp/fpdf_scopers.h" #include "public/fpdf_dataavail.h" #include "public/fpdf_ext.h" #include "public/fpdf_text.h" -#include "testing/test_loader.h" - -#ifdef PDF_ENABLE_V8 -#include "testing/free_deleter.h" -#include "testing/v8_initializer.h" -#include "v8/include/v8-platform.h" -#include "v8/include/v8.h" -#endif +#include "third_party/base/span.h" namespace { +class FuzzerTestLoader { + public: + explicit FuzzerTestLoader(pdfium::span<const char> span) : m_Span(span) {} + + static int GetBlock(void* param, + unsigned long pos, + unsigned char* pBuf, + unsigned long size) { + FuzzerTestLoader* pLoader = static_cast<FuzzerTestLoader*>(param); + if (pos + size < pos || pos + size > pLoader->m_Span.size()) { + NOTREACHED(); + return 0; + } + + memcpy(pBuf, &pLoader->m_Span[pos], size); + return 1; + } + + private: + const pdfium::span<const char> m_Span; +}; + int ExampleAppAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, @@ -78,42 +86,12 @@ FPDF_WIDESTRING BCC, FPDF_WIDESTRING Msg) {} -void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) {} - FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { return true; } void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} -#ifdef PDF_ENABLE_V8 -std::string ProgramPath() { - std::string result; - -#ifdef _WIN32 - char path[MAX_PATH]; - DWORD len = GetModuleFileNameA(NULL, path, MAX_PATH); - if (len != 0) - result = std::string(path, len); -#elif defined(__APPLE__) - char path[PATH_MAX]; - unsigned int len = PATH_MAX; - if (!_NSGetExecutablePath(path, &len)) { - std::unique_ptr<char, pdfium::FreeDeleter> resolved_path( - realpath(path, nullptr)); - if (resolved_path.get()) - result = std::string(resolved_path.get()); - } -#else // Linux - char path[PATH_MAX]; - ssize_t len = readlink("/proc/self/exe", path, PATH_MAX); - if (len > 0) - result = std::string(path, len); -#endif - return result; -} -#endif // PDF_ENABLE_V8 - std::pair<int, int> GetRenderingAndFormFlagFromData(const char* data, size_t len) { std::string data_str = std::string(data, len); @@ -155,11 +133,11 @@ form_callbacks.version = GetFormCallbackVersion(); form_callbacks.m_pJsPlatform = &platform_callbacks; - TestLoader loader({data, len}); + FuzzerTestLoader loader({data, len}); FPDF_FILEACCESS file_access; memset(&file_access, '\0', sizeof(file_access)); file_access.m_FileLen = static_cast<unsigned long>(len); - file_access.m_GetBlock = TestLoader::GetBlock; + file_access.m_GetBlock = FuzzerTestLoader::GetBlock; file_access.m_Param = &loader; FX_FILEAVAIL file_avail; @@ -255,43 +233,3 @@ FORM_OnBeforeClosePage(page.get(), form); return !!bitmap; } - -// Initialize the library once for all runs of the fuzzer. -struct TestCase { - TestCase() { -#ifdef PDF_ENABLE_V8 -#ifdef V8_USE_EXTERNAL_STARTUP_DATA - platform = InitializeV8ForPDFiumWithStartupData( - ProgramPath(), "", &natives_blob, &snapshot_blob); -#else - platform = InitializeV8ForPDFium(ProgramPath()); -#endif // V8_USE_EXTERNAL_STARTUP_DATA -#endif // PDF_ENABLE_V8 - - memset(&config, '\0', sizeof(config)); - config.version = 2; - config.m_pUserFontPaths = nullptr; - config.m_pIsolate = nullptr; - config.m_v8EmbedderSlot = 0; - FPDF_InitLibraryWithConfig(&config); - - memset(&unsupport_info, '\0', sizeof(unsupport_info)); - unsupport_info.version = 1; - unsupport_info.FSDK_UnSupport_Handler = ExampleUnsupportedHandler; - FSDK_SetUnSpObjProcessHandler(&unsupport_info); - } - -#ifdef PDF_ENABLE_V8 - std::unique_ptr<v8::Platform> platform; - v8::StartupData natives_blob; - v8::StartupData snapshot_blob; -#endif - - FPDF_LIBRARY_CONFIG config; - UNSUPPORT_INFO unsupport_info; -}; - -// pdf_fuzzer_init.cc and pdfium_fuzzer_helper.cc are mutually exclusive and -// should not be built together. They deliberately have the same global -// variable. -static TestCase* g_test_case = new TestCase();