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