| Index: testing/libfuzzer/fuzzers/pdfium_fuzzer.cc
|
| diff --git a/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc b/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b2f0d1fff0a482f761f8f5021b70d88bc57fa051
|
| --- /dev/null
|
| +++ b/testing/libfuzzer/fuzzers/pdfium_fuzzer.cc
|
| @@ -0,0 +1,191 @@
|
| +// Copyright (c) 2015 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 <limits.h>
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +#include <string.h>
|
| +
|
| +#include <list>
|
| +#include <sstream>
|
| +#include <string>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#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"
|
| +
|
| +static int ExampleAppAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING,
|
| + int, int) {
|
| + return 0;
|
| +}
|
| +
|
| +static void ExampleDocGotoPage(IPDF_JSPLATFORM*, int pageNumber) { }
|
| +
|
| +static 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) { }
|
| +
|
| +static bool RenderPage(const FPDF_DOCUMENT& doc,
|
| + const FPDF_FORMHANDLE& form,
|
| + const int page_index) {
|
| + FPDF_PAGE page = FPDF_LoadPage(doc, page_index);
|
| + if (!page) {
|
| + return false;
|
| + }
|
| + FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page);
|
| + FORM_OnAfterLoadPage(page, form);
|
| + FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN);
|
| +
|
| + double scale = 1.0;
|
| + int width = static_cast<int>(FPDF_GetPageWidth(page) * scale);
|
| + int height = static_cast<int>(FPDF_GetPageHeight(page) * scale);
|
| +
|
| + FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0);
|
| + if (!bitmap) {
|
| + return false;
|
| + }
|
| +
|
| + FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF);
|
| + FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
|
| +
|
| + FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0);
|
| +
|
| + FPDFBitmap_Destroy(bitmap);
|
| + FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE);
|
| + FORM_OnBeforeClosePage(page, form);
|
| + FPDFText_ClosePage(text_page);
|
| + FPDF_ClosePage(page);
|
| + return true;
|
| +}
|
| +
|
| +static void 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.Doc_gotoPage = ExampleDocGotoPage;
|
| +
|
| + FPDF_FORMFILLINFO form_callbacks;
|
| + memset(&form_callbacks, '\0', sizeof(form_callbacks));
|
| + form_callbacks.version = 1;
|
| + form_callbacks.m_pJsPlatform = &platform_callbacks;
|
| +
|
| + TestLoader loader(pBuf, 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_Param = &loader;
|
| +
|
| + FX_FILEAVAIL file_avail;
|
| + memset(&file_avail, '\0', sizeof(file_avail));
|
| + file_avail.version = 1;
|
| + file_avail.IsDataAvail = Is_Data_Avail;
|
| +
|
| + FX_DOWNLOADHINTS hints;
|
| + memset(&hints, '\0', sizeof(hints));
|
| + hints.version = 1;
|
| + hints.AddSegment = Add_Segment;
|
| +
|
| + FPDF_DOCUMENT doc;
|
| + int nRet = PDF_DATA_NOTAVAIL;
|
| + bool bIsLinearized = false;
|
| + FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access);
|
| +
|
| + if (FPDFAvail_IsLinearized(pdf_avail) == PDF_LINEARIZED) {
|
| + doc = FPDFAvail_GetDocument(pdf_avail, nullptr);
|
| + if (doc) {
|
| + while (nRet == PDF_DATA_NOTAVAIL) {
|
| + nRet = FPDFAvail_IsDocAvail(pdf_avail, &hints);
|
| + }
|
| + if (nRet == PDF_DATA_ERROR) {
|
| + return;
|
| + }
|
| + nRet = FPDFAvail_IsFormAvail(pdf_avail, &hints);
|
| + if (nRet == PDF_FORM_ERROR || nRet == PDF_FORM_NOTAVAIL) {
|
| + return;
|
| + }
|
| + bIsLinearized = true;
|
| + }
|
| + } else {
|
| + doc = FPDF_LoadCustomDocument(&file_access, nullptr);
|
| + }
|
| +
|
| + if (!doc) {
|
| + FPDFAvail_Destroy(pdf_avail);
|
| + return;
|
| + }
|
| +
|
| + (void)FPDF_GetDocPermissions(doc);
|
| +
|
| + FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks);
|
| + FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD);
|
| + FPDF_SetFormFieldHighlightAlpha(form, 100);
|
| +
|
| + FORM_DoDocumentJSAction(form);
|
| + FORM_DoDocumentOpenAction(form);
|
| +
|
| + int page_count = FPDF_GetPageCount(doc);
|
| +
|
| + for (int i = 0; i < page_count; ++i) {
|
| + if (bIsLinearized) {
|
| + nRet = PDF_DATA_NOTAVAIL;
|
| + while (nRet == PDF_DATA_NOTAVAIL) {
|
| + nRet = FPDFAvail_IsPageAvail(pdf_avail, i, &hints);
|
| + }
|
| + if (nRet == PDF_DATA_ERROR) {
|
| + return;
|
| + }
|
| + }
|
| + RenderPage(doc, form, i);
|
| + }
|
| +
|
| + FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC);
|
| + FPDFDOC_ExitFormFillEnvironment(form);
|
| + FPDF_CloseDocument(doc);
|
| + FPDFAvail_Destroy(pdf_avail);
|
| +}
|
| +
|
| +static v8::Platform* Init() {
|
| + v8::Platform* platform;
|
| + InitializeV8ForPDFium(&platform);
|
| +
|
| + FPDF_LIBRARY_CONFIG config;
|
| + config.version = 2;
|
| + config.m_pUserFontPaths = nullptr;
|
| + config.m_pIsolate = nullptr;
|
| + config.m_v8EmbedderSlot = 0;
|
| +
|
| + FPDF_InitLibraryWithConfig(&config);
|
| +
|
| + UNSUPPORT_INFO unsuppored_info;
|
| + memset(&unsuppored_info, '\0', sizeof(unsuppored_info));
|
| + unsuppored_info.version = 1;
|
| + unsuppored_info.FSDK_UnSupport_Handler = ExampleUnsupportedHandler;
|
| +
|
| + FSDK_SetUnSpObjProcessHandler(&unsuppored_info);
|
| +
|
| + return platform;
|
| +}
|
| +
|
| +static v8::Platform* platform = Init();
|
| +
|
| +extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
|
| + RenderPdf(reinterpret_cast<const char*>(data), size);
|
| + return 0;
|
| +}
|
|
|