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 |