| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This fuzzer is simplified & cleaned up pdfium/samples/pdfium_test.cc | 5 // This fuzzer is simplified & cleaned up pdfium/samples/pdfium_test.cc |
| 6 | 6 |
| 7 #include "pdf/pdfium/fuzzers/pdfium_fuzzer_helper.h" |
| 8 |
| 7 #include <assert.h> | 9 #include <assert.h> |
| 8 #include <limits.h> | 10 #include <limits.h> |
| 9 #include <stddef.h> | 11 #include <stddef.h> |
| 10 #include <stdint.h> | 12 #include <stdint.h> |
| 11 #include <stdio.h> | 13 #include <stdio.h> |
| 12 #include <stdlib.h> | 14 #include <stdlib.h> |
| 13 #include <string.h> | 15 #include <string.h> |
| 14 | 16 |
| 15 #ifdef _MSC_VER | 17 #ifdef _MSC_VER |
| 16 #include <Windows.h> | 18 #include <Windows.h> |
| 17 #else | 19 #else |
| 18 #include <unistd.h> | 20 #include <unistd.h> |
| 19 #endif | 21 #endif |
| 20 | 22 |
| 21 #include <list> | |
| 22 #include <memory> | 23 #include <memory> |
| 23 #include <sstream> | 24 #include <sstream> |
| 24 #include <string> | 25 #include <string> |
| 25 #include <utility> | 26 #include <utility> |
| 26 #include <vector> | |
| 27 | 27 |
| 28 #include "third_party/pdfium/public/cpp/fpdf_deleters.h" | 28 #include "third_party/pdfium/public/cpp/fpdf_deleters.h" |
| 29 #include "third_party/pdfium/public/fpdf_dataavail.h" | 29 #include "third_party/pdfium/public/fpdf_dataavail.h" |
| 30 #include "third_party/pdfium/public/fpdf_ext.h" | |
| 31 #include "third_party/pdfium/public/fpdf_formfill.h" | |
| 32 #include "third_party/pdfium/public/fpdf_text.h" | 30 #include "third_party/pdfium/public/fpdf_text.h" |
| 33 #include "third_party/pdfium/public/fpdfview.h" | |
| 34 #include "third_party/pdfium/testing/test_support.h" | 31 #include "third_party/pdfium/testing/test_support.h" |
| 35 | 32 |
| 36 #include "v8/include/v8.h" | 33 namespace { |
| 37 | 34 |
| 38 static int ExampleAppAlert(IPDF_JSPLATFORM*, | 35 int ExampleAppAlert(IPDF_JSPLATFORM*, |
| 39 FPDF_WIDESTRING, | 36 FPDF_WIDESTRING, |
| 40 FPDF_WIDESTRING, | 37 FPDF_WIDESTRING, |
| 41 int, | 38 int, |
| 42 int) { | 39 int) { |
| 43 return 0; | 40 return 0; |
| 44 } | 41 } |
| 45 | 42 |
| 46 static void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) {} | 43 int ExampleAppResponse(IPDF_JSPLATFORM*, |
| 44 FPDF_WIDESTRING question, |
| 45 FPDF_WIDESTRING title, |
| 46 FPDF_WIDESTRING default_value, |
| 47 FPDF_WIDESTRING label, |
| 48 FPDF_BOOL is_password, |
| 49 void* response, |
| 50 int length) { |
| 51 // UTF-16, always LE regardless of platform. |
| 52 uint8_t* ptr = static_cast<uint8_t*>(response); |
| 53 ptr[0] = 'N'; |
| 54 ptr[1] = 0; |
| 55 ptr[2] = 'o'; |
| 56 ptr[3] = 0; |
| 57 return 4; |
| 58 } |
| 47 | 59 |
| 48 static void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) {} | 60 void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) {} |
| 61 |
| 62 void ExampleDocMail(IPDF_JSPLATFORM*, |
| 63 void* mailData, |
| 64 int length, |
| 65 FPDF_BOOL UI, |
| 66 FPDF_WIDESTRING To, |
| 67 FPDF_WIDESTRING Subject, |
| 68 FPDF_WIDESTRING CC, |
| 69 FPDF_WIDESTRING BCC, |
| 70 FPDF_WIDESTRING Msg) {} |
| 71 |
| 72 void ExampleUnsupportedHandler(UNSUPPORT_INFO*, int type) {} |
| 49 | 73 |
| 50 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { | 74 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { |
| 51 return true; | 75 return true; |
| 52 } | 76 } |
| 53 | 77 |
| 54 static void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} | 78 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) {} |
| 55 | 79 |
| 56 static bool RenderPage(const FPDF_DOCUMENT& doc, | 80 std::string ProgramPath() { |
| 57 const FPDF_FORMHANDLE& form, | 81 #ifdef _MSC_VER |
| 58 const int page_index) { | 82 wchar_t wpath[MAX_PATH]; |
| 59 std::unique_ptr<void, FPDFPageDeleter> page(FPDF_LoadPage(doc, page_index)); | 83 char path[MAX_PATH]; |
| 60 if (!page) | 84 DWORD res = GetModuleFileName(NULL, wpath, MAX_PATH); |
| 61 return false; | 85 assert(res != 0); |
| 62 | 86 wcstombs(path, wpath, MAX_PATH); |
| 63 std::unique_ptr<void, FPDFTextPageDeleter> text_page( | 87 return std::string(path, res); |
| 64 FPDFText_LoadPage(page.get())); | 88 #else |
| 65 FORM_OnAfterLoadPage(page.get(), form); | 89 char* path = new char[PATH_MAX + 1]; |
| 66 FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_OPEN); | 90 assert(path); |
| 67 | 91 ssize_t sz = readlink("/proc/self/exe", path, PATH_MAX); |
| 68 const double scale = 1.0; | 92 assert(sz > 0); |
| 69 int width = static_cast<int>(FPDF_GetPageWidth(page.get()) * scale); | 93 std::string result(path, sz); |
| 70 int height = static_cast<int>(FPDF_GetPageHeight(page.get()) * scale); | 94 delete[] path; |
| 71 std::unique_ptr<void, FPDFBitmapDeleter> bitmap( | 95 return result; |
| 72 FPDFBitmap_Create(width, height, 0)); | 96 #endif |
| 73 if (bitmap) { | |
| 74 FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF); | |
| 75 FPDF_RenderPageBitmap(bitmap.get(), page.get(), 0, 0, width, height, 0, 0); | |
| 76 FPDF_FFLDraw(form, bitmap.get(), page.get(), 0, 0, width, height, 0, 0); | |
| 77 } | |
| 78 FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_CLOSE); | |
| 79 FORM_OnBeforeClosePage(page.get(), form); | |
| 80 return !!bitmap; | |
| 81 } | 97 } |
| 82 | 98 |
| 83 static void RenderPdf(const char* pBuf, size_t len) { | 99 } // namespace |
| 100 |
| 101 PDFiumFuzzerHelper::PDFiumFuzzerHelper() {} |
| 102 |
| 103 PDFiumFuzzerHelper::~PDFiumFuzzerHelper() {} |
| 104 |
| 105 bool PDFiumFuzzerHelper::OnFormFillEnvLoaded(FPDF_DOCUMENT doc) { |
| 106 return true; |
| 107 } |
| 108 |
| 109 void PDFiumFuzzerHelper::RenderPdf(const char* pBuf, size_t len) { |
| 84 IPDF_JSPLATFORM platform_callbacks; | 110 IPDF_JSPLATFORM platform_callbacks; |
| 85 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); | 111 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); |
| 86 platform_callbacks.version = 3; | 112 platform_callbacks.version = 3; |
| 87 platform_callbacks.app_alert = ExampleAppAlert; | 113 platform_callbacks.app_alert = ExampleAppAlert; |
| 114 platform_callbacks.app_response = ExampleAppResponse; |
| 88 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; | 115 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; |
| 116 platform_callbacks.Doc_mail = ExampleDocMail; |
| 89 | 117 |
| 90 FPDF_FORMFILLINFO form_callbacks; | 118 FPDF_FORMFILLINFO form_callbacks; |
| 91 memset(&form_callbacks, '\0', sizeof(form_callbacks)); | 119 memset(&form_callbacks, '\0', sizeof(form_callbacks)); |
| 92 form_callbacks.version = 1; | 120 form_callbacks.version = GetFormCallbackVersion(); |
| 93 form_callbacks.m_pJsPlatform = &platform_callbacks; | 121 form_callbacks.m_pJsPlatform = &platform_callbacks; |
| 94 | 122 |
| 95 TestLoader loader(pBuf, len); | 123 TestLoader loader(pBuf, len); |
| 96 FPDF_FILEACCESS file_access; | 124 FPDF_FILEACCESS file_access; |
| 97 memset(&file_access, '\0', sizeof(file_access)); | 125 memset(&file_access, '\0', sizeof(file_access)); |
| 98 file_access.m_FileLen = static_cast<unsigned long>(len); | 126 file_access.m_FileLen = static_cast<unsigned long>(len); |
| 99 file_access.m_GetBlock = TestLoader::GetBlock; | 127 file_access.m_GetBlock = TestLoader::GetBlock; |
| 100 file_access.m_Param = &loader; | 128 file_access.m_Param = &loader; |
| 101 | 129 |
| 102 FX_FILEAVAIL file_avail; | 130 FX_FILEAVAIL file_avail; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 doc.reset(FPDF_LoadCustomDocument(&file_access, nullptr)); | 162 doc.reset(FPDF_LoadCustomDocument(&file_access, nullptr)); |
| 135 } | 163 } |
| 136 | 164 |
| 137 if (!doc) | 165 if (!doc) |
| 138 return; | 166 return; |
| 139 | 167 |
| 140 (void)FPDF_GetDocPermissions(doc.get()); | 168 (void)FPDF_GetDocPermissions(doc.get()); |
| 141 | 169 |
| 142 std::unique_ptr<void, FPDFFormHandleDeleter> form( | 170 std::unique_ptr<void, FPDFFormHandleDeleter> form( |
| 143 FPDFDOC_InitFormFillEnvironment(doc.get(), &form_callbacks)); | 171 FPDFDOC_InitFormFillEnvironment(doc.get(), &form_callbacks)); |
| 172 if (!OnFormFillEnvLoaded(doc.get())) |
| 173 return; |
| 174 |
| 144 FPDF_SetFormFieldHighlightColor(form.get(), 0, 0xFFE4DD); | 175 FPDF_SetFormFieldHighlightColor(form.get(), 0, 0xFFE4DD); |
| 145 FPDF_SetFormFieldHighlightAlpha(form.get(), 100); | 176 FPDF_SetFormFieldHighlightAlpha(form.get(), 100); |
| 146 FORM_DoDocumentJSAction(form.get()); | 177 FORM_DoDocumentJSAction(form.get()); |
| 147 FORM_DoDocumentOpenAction(form.get()); | 178 FORM_DoDocumentOpenAction(form.get()); |
| 148 | 179 |
| 149 int page_count = FPDF_GetPageCount(doc.get()); | 180 int page_count = FPDF_GetPageCount(doc.get()); |
| 150 for (int i = 0; i < page_count; ++i) { | 181 for (int i = 0; i < page_count; ++i) { |
| 151 if (bIsLinearized) { | 182 if (bIsLinearized) { |
| 152 nRet = PDF_DATA_NOTAVAIL; | 183 nRet = PDF_DATA_NOTAVAIL; |
| 153 while (nRet == PDF_DATA_NOTAVAIL) | 184 while (nRet == PDF_DATA_NOTAVAIL) |
| 154 nRet = FPDFAvail_IsPageAvail(pdf_avail.get(), i, &hints); | 185 nRet = FPDFAvail_IsPageAvail(pdf_avail.get(), i, &hints); |
| 155 | 186 |
| 156 if (nRet == PDF_DATA_ERROR) | 187 if (nRet == PDF_DATA_ERROR) |
| 157 return; | 188 return; |
| 158 } | 189 } |
| 159 RenderPage(doc.get(), form.get(), i); | 190 RenderPage(doc.get(), form.get(), i); |
| 160 } | 191 } |
| 161 FORM_DoDocumentAAction(form.get(), FPDFDOC_AACTION_WC); | 192 FORM_DoDocumentAAction(form.get(), FPDFDOC_AACTION_WC); |
| 162 } | 193 } |
| 163 | 194 |
| 164 std::string ProgramPath() { | 195 bool PDFiumFuzzerHelper::RenderPage(const FPDF_DOCUMENT& doc, |
| 165 #ifdef _MSC_VER | 196 const FPDF_FORMHANDLE& form, |
| 166 wchar_t wpath[MAX_PATH]; | 197 const int page_index) { |
| 167 char path[MAX_PATH]; | 198 std::unique_ptr<void, FPDFPageDeleter> page(FPDF_LoadPage(doc, page_index)); |
| 168 DWORD res = GetModuleFileName(NULL, wpath, MAX_PATH); | 199 if (!page) |
| 169 assert(res != 0); | 200 return false; |
| 170 wcstombs(path, wpath, MAX_PATH); | 201 |
| 171 return std::string(path, res); | 202 std::unique_ptr<void, FPDFTextPageDeleter> text_page( |
| 172 #else | 203 FPDFText_LoadPage(page.get())); |
| 173 char* path = new char[PATH_MAX + 1]; | 204 FORM_OnAfterLoadPage(page.get(), form); |
| 174 assert(path); | 205 FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_OPEN); |
| 175 ssize_t sz = readlink("/proc/self/exe", path, PATH_MAX); | 206 |
| 176 assert(sz > 0); | 207 const double scale = 1.0; |
| 177 std::string result(path, sz); | 208 int width = static_cast<int>(FPDF_GetPageWidth(page.get()) * scale); |
| 178 delete[] path; | 209 int height = static_cast<int>(FPDF_GetPageHeight(page.get()) * scale); |
| 179 return result; | 210 std::unique_ptr<void, FPDFBitmapDeleter> bitmap( |
| 180 #endif | 211 FPDFBitmap_Create(width, height, 0)); |
| 212 if (bitmap) { |
| 213 FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, 0xFFFFFFFF); |
| 214 FPDF_RenderPageBitmap(bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
| 215 FPDF_FFLDraw(form, bitmap.get(), page.get(), 0, 0, width, height, 0, 0); |
| 216 } |
| 217 FORM_DoPageAAction(page.get(), form, FPDFPAGE_AACTION_CLOSE); |
| 218 FORM_OnBeforeClosePage(page.get(), form); |
| 219 return !!bitmap; |
| 181 } | 220 } |
| 182 | 221 |
| 222 // Initialize the library once for all runs of the fuzzer. |
| 183 struct TestCase { | 223 struct TestCase { |
| 184 TestCase() { | 224 TestCase() { |
| 185 InitializeV8ForPDFium(ProgramPath(), "", &natives_blob, &snapshot_blob, | 225 InitializeV8ForPDFium(ProgramPath(), "", &natives_blob, &snapshot_blob, |
| 186 &platform); | 226 &platform); |
| 187 | 227 |
| 188 memset(&config, '\0', sizeof(config)); | 228 memset(&config, '\0', sizeof(config)); |
| 189 config.version = 2; | 229 config.version = 2; |
| 190 config.m_pUserFontPaths = nullptr; | 230 config.m_pUserFontPaths = nullptr; |
| 191 config.m_pIsolate = nullptr; | 231 config.m_pIsolate = nullptr; |
| 192 config.m_v8EmbedderSlot = 0; | 232 config.m_v8EmbedderSlot = 0; |
| 193 FPDF_InitLibraryWithConfig(&config); | 233 FPDF_InitLibraryWithConfig(&config); |
| 194 | 234 |
| 195 memset(&unsupport_info, '\0', sizeof(unsupport_info)); | 235 memset(&unsupport_info, '\0', sizeof(unsupport_info)); |
| 196 unsupport_info.version = 1; | 236 unsupport_info.version = 1; |
| 197 unsupport_info.FSDK_UnSupport_Handler = ExampleUnsupportedHandler; | 237 unsupport_info.FSDK_UnSupport_Handler = ExampleUnsupportedHandler; |
| 198 FSDK_SetUnSpObjProcessHandler(&unsupport_info); | 238 FSDK_SetUnSpObjProcessHandler(&unsupport_info); |
| 199 } | 239 } |
| 200 | 240 |
| 201 v8::Platform* platform; | 241 v8::Platform* platform; |
| 202 v8::StartupData natives_blob; | 242 v8::StartupData natives_blob; |
| 203 v8::StartupData snapshot_blob; | 243 v8::StartupData snapshot_blob; |
| 204 FPDF_LIBRARY_CONFIG config; | 244 FPDF_LIBRARY_CONFIG config; |
| 205 UNSUPPORT_INFO unsupport_info; | 245 UNSUPPORT_INFO unsupport_info; |
| 206 }; | 246 }; |
| 207 | |
| 208 static TestCase* testCase = new TestCase(); | 247 static TestCase* testCase = new TestCase(); |
| 209 | |
| 210 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | |
| 211 RenderPdf(reinterpret_cast<const char*>(data), size); | |
| 212 return 0; | |
| 213 } | |
| OLD | NEW |