Index: pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc |
diff --git a/pdf/pdfium/fuzzers/pdfium_fuzzer.cc b/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc |
similarity index 72% |
copy from pdf/pdfium/fuzzers/pdfium_fuzzer.cc |
copy to pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc |
index 658be7eca6796a2b884a560022e5b5c88a3a610c..3d49a0a7c36a3b9346762241a77e156e64e4b656 100644 |
--- a/pdf/pdfium/fuzzers/pdfium_fuzzer.cc |
+++ b/pdf/pdfium/fuzzers/pdfium_fuzzer_helper.cc |
@@ -1,9 +1,11 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
// This fuzzer is simplified & cleaned up pdfium/samples/pdfium_test.cc |
+#include "pdf/pdfium/fuzzers/pdfium_fuzzer_helper.h" |
+ |
#include <assert.h> |
#include <limits.h> |
#include <stddef.h> |
@@ -18,78 +20,104 @@ |
#include <unistd.h> |
#endif |
-#include <list> |
#include <memory> |
#include <sstream> |
#include <string> |
#include <utility> |
-#include <vector> |
#include "third_party/pdfium/public/cpp/fpdf_deleters.h" |
#include "third_party/pdfium/public/fpdf_dataavail.h" |
-#include "third_party/pdfium/public/fpdf_ext.h" |
-#include "third_party/pdfium/public/fpdf_formfill.h" |
#include "third_party/pdfium/public/fpdf_text.h" |
-#include "third_party/pdfium/public/fpdfview.h" |
#include "third_party/pdfium/testing/test_support.h" |
-#include "v8/include/v8.h" |
+namespace { |
-static int ExampleAppAlert(IPDF_JSPLATFORM*, |
- FPDF_WIDESTRING, |
- FPDF_WIDESTRING, |
- int, |
- int) { |
+int ExampleAppAlert(IPDF_JSPLATFORM*, |
+ FPDF_WIDESTRING, |
+ FPDF_WIDESTRING, |
+ int, |
+ int) { |
return 0; |
} |
-static void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) {} |
+int ExampleAppResponse(IPDF_JSPLATFORM*, |
+ FPDF_WIDESTRING question, |
+ FPDF_WIDESTRING title, |
+ FPDF_WIDESTRING default_value, |
+ FPDF_WIDESTRING label, |
+ FPDF_BOOL is_password, |
+ void* response, |
+ int length) { |
+ // UTF-16, always LE regardless of platform. |
+ uint8_t* ptr = static_cast<uint8_t*>(response); |
+ ptr[0] = 'N'; |
+ ptr[1] = 0; |
+ ptr[2] = 'o'; |
+ ptr[3] = 0; |
+ return 4; |
+} |
+ |
+void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) {} |
-static void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) {} |
+void ExampleDocMail(IPDF_JSPLATFORM*, |
+ void* mailData, |
+ int length, |
+ FPDF_BOOL UI, |
+ FPDF_WIDESTRING To, |
+ FPDF_WIDESTRING Subject, |
+ FPDF_WIDESTRING CC, |
+ 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; |
} |
-static void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} |
+void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} |
-static bool RenderPage(const FPDF_DOCUMENT& doc, |
- const FPDF_FORMHANDLE& form, |
- const int page_index) { |
- std::unique_ptr<void, FPDFPageDeleter> page(FPDF_LoadPage(doc, page_index)); |
- if (!page) |
- return false; |
+std::string ProgramPath() { |
+#ifdef _MSC_VER |
+ wchar_t wpath[MAX_PATH]; |
+ char path[MAX_PATH]; |
+ DWORD res = GetModuleFileName(NULL, wpath, MAX_PATH); |
+ assert(res != 0); |
+ wcstombs(path, wpath, MAX_PATH); |
+ return std::string(path, res); |
+#else |
+ char* path = new char[PATH_MAX + 1]; |
+ assert(path); |
+ ssize_t sz = readlink("/proc/self/exe", path, PATH_MAX); |
+ assert(sz > 0); |
+ std::string result(path, sz); |
+ delete[] path; |
+ return result; |
+#endif |
+} |
- std::unique_ptr<void, FPDFTextPageDeleter> text_page( |
- FPDFText_LoadPage(page.get())); |
- FORM_OnAfterLoadPage(page.get(), form); |
- FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_OPEN); |
+} // namespace |
- const double scale = 1.0; |
- int width = static_cast<int>(FPDF_GetPageWidth(page.get()) * scale); |
- int height = static_cast<int>(FPDF_GetPageHeight(page.get()) * scale); |
- std::unique_ptr<void, FPDFBitmapDeleter> bitmap( |
- FPDFBitmap_Create(width, height, 0)); |
- if (bitmap) { |
- FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF); |
- FPDF_RenderPageBitmap(bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
- FPDF_FFLDraw(form, bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
- } |
- FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_CLOSE); |
- FORM_OnBeforeClosePage(page.get(), form); |
- return !!bitmap; |
+PDFiumFuzzerHelper::PDFiumFuzzerHelper() {} |
+ |
+PDFiumFuzzerHelper::~PDFiumFuzzerHelper() {} |
+ |
+bool PDFiumFuzzerHelper::OnFormFillEnvLoaded(FPDF_DOCUMENT doc) { |
+ return true; |
} |
-static void RenderPdf(const char* pBuf, size_t len) { |
+void PDFiumFuzzerHelper::RenderPdf(const char* pBuf, size_t len) { |
IPDF_JSPLATFORM platform_callbacks; |
memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); |
platform_callbacks.version = 3; |
platform_callbacks.app_alert = ExampleAppAlert; |
+ platform_callbacks.app_response = ExampleAppResponse; |
platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; |
+ platform_callbacks.Doc_mail = ExampleDocMail; |
FPDF_FORMFILLINFO form_callbacks; |
memset(&form_callbacks, '\0', sizeof(form_callbacks)); |
- form_callbacks.version = 1; |
+ form_callbacks.version = GetFormCallbackVersion(); |
form_callbacks.m_pJsPlatform = &platform_callbacks; |
TestLoader loader(pBuf, len); |
@@ -141,6 +169,9 @@ static void RenderPdf(const char* pBuf, size_t len) { |
std::unique_ptr<void, FPDFFormHandleDeleter> form( |
FPDFDOC_InitFormFillEnvironment(doc.get(), &form_callbacks)); |
+ if (!OnFormFillEnvLoaded(doc.get())) |
+ return; |
+ |
FPDF_SetFormFieldHighlightColor(form.get(), 0, 0xFFE4DD); |
FPDF_SetFormFieldHighlightAlpha(form.get(), 100); |
FORM_DoDocumentJSAction(form.get()); |
@@ -161,25 +192,34 @@ static void RenderPdf(const char* pBuf, size_t len) { |
FORM_DoDocumentAAction(form.get(), FPDFDOC_AACTION_WC); |
} |
-std::string ProgramPath() { |
-#ifdef _MSC_VER |
- wchar_t wpath[MAX_PATH]; |
- char path[MAX_PATH]; |
- DWORD res = GetModuleFileName(NULL, wpath, MAX_PATH); |
- assert(res != 0); |
- wcstombs(path, wpath, MAX_PATH); |
- return std::string(path, res); |
-#else |
- char* path = new char[PATH_MAX + 1]; |
- assert(path); |
- ssize_t sz = readlink("/proc/self/exe", path, PATH_MAX); |
- assert(sz > 0); |
- std::string result(path, sz); |
- delete[] path; |
- return result; |
-#endif |
+bool PDFiumFuzzerHelper::RenderPage(const FPDF_DOCUMENT& doc, |
+ const FPDF_FORMHANDLE& form, |
+ const int page_index) { |
+ std::unique_ptr<void, FPDFPageDeleter> page(FPDF_LoadPage(doc, page_index)); |
+ if (!page) |
+ return false; |
+ |
+ std::unique_ptr<void, FPDFTextPageDeleter> text_page( |
+ FPDFText_LoadPage(page.get())); |
+ FORM_OnAfterLoadPage(page.get(), form); |
+ FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_OPEN); |
+ |
+ const double scale = 1.0; |
+ int width = static_cast<int>(FPDF_GetPageWidth(page.get()) * scale); |
+ int height = static_cast<int>(FPDF_GetPageHeight(page.get()) * scale); |
+ std::unique_ptr<void, FPDFBitmapDeleter> bitmap( |
+ FPDFBitmap_Create(width, height, 0)); |
+ if (bitmap) { |
+ FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF); |
+ FPDF_RenderPageBitmap(bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
+ FPDF_FFLDraw(form, bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
+ } |
+ FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_CLOSE); |
+ FORM_OnBeforeClosePage(page.get(), form); |
+ return !!bitmap; |
} |
+// Initialize the library once for all runs of the fuzzer. |
struct TestCase { |
TestCase() { |
InitializeV8ForPDFium(ProgramPath(), "", &natives_blob, &snapshot_blob, |
@@ -204,10 +244,4 @@ struct TestCase { |
FPDF_LIBRARY_CONFIG config; |
UNSUPPORT_INFO unsupport_info; |
}; |
- |
static TestCase* testCase = new TestCase(); |
- |
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
- RenderPdf(reinterpret_cast<const char*>(data), size); |
- return 0; |
-} |