add a rtf to pdf fuzzer
Change-Id: Ib805b2e8245903f63096cc21f511ba7ae0a4f488 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173466 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
@@ -140,6 +140,7 @@ $(eval $(call gb_Helper_register_executables_for_install,OOO,brand, \
|
||||
$(call gb_Helper_optional,FUZZERS,olefuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,pptfuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,rtffuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,rtf2pdffuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,cgmfuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,ww2fuzzer) \
|
||||
$(call gb_Helper_optional,FUZZERS,ww6fuzzer) \
|
||||
|
||||
@@ -166,6 +166,7 @@ curl --no-progress-meter -S \
|
||||
-C - -O https://dev-www.libreoffice.org/corpus/htmlfuzzer_seed_corpus.zip \
|
||||
-C - -O https://dev-www.libreoffice.org/corpus/zipfuzzer_seed_corpus.zip
|
||||
cp fodtfuzzer_seed_corpus.zip fodt2pdffuzzer_seed_corpus.zip
|
||||
cp rtffuzzer_seed_corpus.zip rtf2pdffuzzer_seed_corpus.zip
|
||||
cp fodsfuzzer_seed_corpus.zip fods2xlsfuzzer_seed_corpus.zip
|
||||
cp htmlfuzzer_seed_corpus.zip schtmlfuzzer_seed_corpus.zip
|
||||
|
||||
|
||||
+1
-1
@@ -204,6 +204,7 @@ namespace o3tl {
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDOC(SvStream &rStream, const OUString &rFltName);
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportDOCX(SvStream &rStream);
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportRTF(SvStream &rStream);
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestPDFExportRTF(SvStream &rStream);
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportHTML(SvStream &rStream);
|
||||
SAL_DLLPUBLIC_EXPORT void FlushFontCache();
|
||||
|
||||
@@ -211,7 +212,6 @@ class SW_DLLPUBLIC Reader
|
||||
{
|
||||
friend class SwReader;
|
||||
friend bool TestImportDOC(SvStream &rStream, const OUString &rFltName);
|
||||
friend bool TestImportRTF(SvStream &rStream);
|
||||
friend bool TestImportHTML(SvStream &rStream);
|
||||
rtl::Reference<SwDoc> mxTemplate;
|
||||
OUString m_aTemplateName;
|
||||
|
||||
@@ -28,15 +28,22 @@
|
||||
|
||||
#include <unotextrange.hxx>
|
||||
|
||||
#include <unotools/fcm.hxx>
|
||||
#include <unotools/streamwrap.hxx>
|
||||
#include <unotools/tempfile.hxx>
|
||||
#include <comphelper/processfactory.hxx>
|
||||
#include <comphelper/propertysequence.hxx>
|
||||
#include <comphelper/diagnose_ex.hxx>
|
||||
|
||||
#include <com/sun/star/document/XFilter.hpp>
|
||||
#include <com/sun/star/document/XExporter.hpp>
|
||||
#include <com/sun/star/document/XImporter.hpp>
|
||||
#include <com/sun/star/frame/Desktop.hpp>
|
||||
#include <com/sun/star/frame/XLoadable.hpp>
|
||||
#include <com/sun/star/frame/XModel.hpp>
|
||||
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
||||
#include <com/sun/star/text/XTextDocument.hpp>
|
||||
#include <com/sun/star/util/XCloseable.hpp>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
@@ -209,4 +216,111 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportRTF(SvStream& rStream)
|
||||
return bRet;
|
||||
}
|
||||
|
||||
extern "C" SAL_DLLPUBLIC_EXPORT bool TestPDFExportRTF(SvStream& rStream)
|
||||
{
|
||||
#if 0
|
||||
//TODO: probably end up needing one of these too
|
||||
// do the same sort of check as FilterDetect::detect
|
||||
OString const str(read_uInt8s_ToOString(rStream, 4000));
|
||||
rStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
OUString resultString(str.getStr(), str.getLength(), RTL_TEXTENCODING_ASCII_US,
|
||||
RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT
|
||||
| RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT
|
||||
| RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT);
|
||||
if (!resultString.startsWith("<?xml")
|
||||
|| resultString.indexOf("office:mimetype=\"application/vnd.oasis.opendocument.text\"")
|
||||
== -1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
uno::Reference<css::frame::XDesktop2> xDesktop
|
||||
= css::frame::Desktop::create(comphelper::getProcessComponentContext());
|
||||
uno::Reference<css::frame::XFrame> xTargetFrame = xDesktop->findFrame(u"_blank"_ustr, 0);
|
||||
|
||||
uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
|
||||
uno::Reference<css::frame::XModel2> xModel(
|
||||
xContext->getServiceManager()->createInstanceWithContext(
|
||||
u"com.sun.star.text.TextDocument"_ustr, xContext),
|
||||
uno::UNO_QUERY_THROW);
|
||||
|
||||
uno::Reference<css::frame::XLoadable> xModelLoad(xModel, uno::UNO_QUERY_THROW);
|
||||
xModelLoad->initNew();
|
||||
|
||||
uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(
|
||||
comphelper::getProcessServiceFactory());
|
||||
uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
|
||||
|
||||
uno::Reference<uno::XInterface> xInterface(
|
||||
xMultiServiceFactory->createInstance(u"com.sun.star.comp.Writer.RtfFilter"_ustr),
|
||||
uno::UNO_SET_THROW);
|
||||
|
||||
uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
|
||||
xImporter->setTargetDocument(xModel);
|
||||
|
||||
uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
|
||||
uno::Sequence<beans::PropertyValue> aArgs(
|
||||
comphelper::InitPropertySequence({ { "InputStream", uno::Any(xStream) } }));
|
||||
|
||||
bool ret = true;
|
||||
try
|
||||
{
|
||||
ret = xFilter->filter(aArgs);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
uno::Reference<text::XTextDocument> xTextDocument(xModel, uno::UNO_QUERY);
|
||||
uno::Reference<text::XText> xText(xTextDocument->getText());
|
||||
uno::Reference<container::XEnumerationAccess> xParaAccess(xText, uno::UNO_QUERY);
|
||||
uno::Reference<container::XEnumeration> xParaEnum(xParaAccess->createEnumeration());
|
||||
while (xParaEnum->hasMoreElements())
|
||||
{
|
||||
uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
|
||||
// discourage very long paragraphs for fuzzing performance
|
||||
if (xPara && xPara->getString().getLength() > 15000)
|
||||
{
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
css::uno::Reference<css::frame::XController2> xController(
|
||||
xModel->createDefaultViewController(xTargetFrame), uno::UNO_SET_THROW);
|
||||
utl::ConnectFrameControllerModel(xTargetFrame, xController, xModel);
|
||||
|
||||
utl::TempFileFast aTempFile;
|
||||
|
||||
uno::Reference<document::XFilter> xPDFFilter(
|
||||
xMultiServiceFactory->createInstance(u"com.sun.star.document.PDFFilter"_ustr),
|
||||
uno::UNO_QUERY);
|
||||
uno::Reference<document::XExporter> xExporter(xPDFFilter, uno::UNO_QUERY);
|
||||
xExporter->setSourceDocument(xModel);
|
||||
|
||||
uno::Reference<io::XOutputStream> xOutputStream(
|
||||
new utl::OStreamWrapper(*aTempFile.GetStream(StreamMode::READWRITE)));
|
||||
|
||||
// ofz#60533 fuzzer learned to use fo:font-size="842pt" which generate timeouts trying
|
||||
// to export thousands of pages from minimal input size
|
||||
uno::Sequence<beans::PropertyValue> aFilterData(
|
||||
comphelper::InitPropertySequence({ { "PageRange", uno::Any(u"1-100"_ustr) } }));
|
||||
uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence(
|
||||
{ { "FilterName", uno::Any(u"writer_pdf_Export"_ustr) },
|
||||
{ "OutputStream", uno::Any(xOutputStream) },
|
||||
{ "FilterData", uno::Any(aFilterData) } }));
|
||||
xPDFFilter->filter(aDescriptor);
|
||||
}
|
||||
|
||||
css::uno::Reference<css::util::XCloseable> xClose(xModel, css::uno::UNO_QUERY);
|
||||
xClose->close(false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
@@ -1833,14 +1833,14 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool TestPDFExportFODT(SvStream &rStream)
|
||||
if (!resultString.startsWith("<?xml") || resultString.indexOf("office:mimetype=\"application/vnd.oasis.opendocument.text\"") == -1)
|
||||
return false;
|
||||
|
||||
Reference<css::frame::XDesktop2> xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext());
|
||||
Reference<css::frame::XFrame> xTargetFrame = xDesktop->findFrame(u"_blank"_ustr, 0);
|
||||
uno::Reference<css::frame::XDesktop2> xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext());
|
||||
uno::Reference<css::frame::XFrame> xTargetFrame = xDesktop->findFrame(u"_blank"_ustr, 0);
|
||||
|
||||
Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
|
||||
Reference<css::frame::XModel2> xModel(xContext->getServiceManager()->createInstanceWithContext(
|
||||
u"com.sun.star.text.TextDocument"_ustr, xContext), UNO_QUERY_THROW);
|
||||
uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
|
||||
uno::Reference<css::frame::XModel2> xModel(xContext->getServiceManager()->createInstanceWithContext(
|
||||
u"com.sun.star.text.TextDocument"_ustr, xContext), uno::UNO_QUERY_THROW);
|
||||
|
||||
Reference<css::frame::XLoadable> xModelLoad(xModel, UNO_QUERY_THROW);
|
||||
uno::Reference<css::frame::XLoadable> xModelLoad(xModel, uno::UNO_QUERY_THROW);
|
||||
xModelLoad->initNew();
|
||||
|
||||
uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
|
||||
@@ -1909,7 +1909,7 @@ extern "C" SAL_DLLPUBLIC_EXPORT bool TestPDFExportFODT(SvStream &rStream)
|
||||
|
||||
if (ret)
|
||||
{
|
||||
css::uno::Reference<css::frame::XController2> xController(xModel->createDefaultViewController(xTargetFrame), UNO_SET_THROW);
|
||||
css::uno::Reference<css::frame::XController2> xController(xModel->createDefaultViewController(xTargetFrame), uno::UNO_SET_THROW);
|
||||
utl::ConnectFrameControllerModel(xTargetFrame, xController, xModel);
|
||||
|
||||
utl::TempFileFast aTempFile;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
|
||||
include $(SRCDIR)/vcl/commonfuzzer.mk
|
||||
|
||||
$(eval $(call gb_Executable_Executable,rtf2pdffuzzer))
|
||||
|
||||
$(eval $(call gb_Executable_use_api,rtf2pdffuzzer,\
|
||||
offapi \
|
||||
udkapi \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_use_externals,rtf2pdffuzzer,\
|
||||
$(fuzzer_externals) \
|
||||
epubgen \
|
||||
revenge \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_set_include,rtf2pdffuzzer,\
|
||||
$$(INCLUDE) \
|
||||
-I$(SRCDIR)/vcl/inc \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_use_libraries,rtf2pdffuzzer,\
|
||||
$(fuzzer_writer_libraries) \
|
||||
$(fuzzer_core_libraries) \
|
||||
pdffilter \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_use_static_libraries,rtf2pdffuzzer,\
|
||||
$(fuzzer_statics) \
|
||||
fuzzer_writer \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_add_exception_objects,rtf2pdffuzzer,\
|
||||
vcl/workben/rtf2pdffuzzer \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Executable_add_libs,rtf2pdffuzzer,\
|
||||
$(LIB_FUZZING_ENGINE) \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
@@ -183,6 +183,7 @@ $(eval $(call gb_Module_add_targets,vcl,\
|
||||
Executable_olefuzzer \
|
||||
Executable_pptfuzzer \
|
||||
Executable_rtffuzzer \
|
||||
Executable_rtf2pdffuzzer \
|
||||
Executable_cgmfuzzer \
|
||||
Executable_ww2fuzzer \
|
||||
Executable_ww6fuzzer \
|
||||
|
||||
@@ -332,6 +332,16 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
|
||||
SvFileStream aFileStream(out, StreamMode::READ);
|
||||
ret = static_cast<int>((*pfnImport)(aFileStream));
|
||||
}
|
||||
else if (strcmp(argv[2], "rtf2pdf") == 0)
|
||||
{
|
||||
static FFilterCall pfnImport(nullptr);
|
||||
if (!pfnImport)
|
||||
{
|
||||
pfnImport = load(u"libmswordlo.so", "TestPDFExportRTF");
|
||||
}
|
||||
SvFileStream aFileStream(out, StreamMode::READ);
|
||||
ret = static_cast<int>((*pfnImport)(aFileStream));
|
||||
}
|
||||
else if (strcmp(argv[2], "fods2xls") == 0)
|
||||
{
|
||||
static FFilterCall pfnImport(nullptr);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <tools/stream.hxx>
|
||||
#include <vcl/FilterConfigItem.hxx>
|
||||
#include <com/sun/star/awt/XToolkit.hpp>
|
||||
#include <com/sun/star/ucb/XContentProvider.hpp>
|
||||
#include <com/sun/star/ucb/XUniversalContentBroker.hpp>
|
||||
#include <libxml/parser.h>
|
||||
#include "commonfuzzer.hxx"
|
||||
|
||||
extern "C" bool TestPDFExportRTF(SvStream& rStream);
|
||||
|
||||
static void silent_error_func(void*, const char* /*format*/, ...) {}
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
|
||||
{
|
||||
if (__lsan_disable)
|
||||
__lsan_disable();
|
||||
|
||||
CommonInitialize(argc, argv);
|
||||
|
||||
// initialise unconfigured UCB:
|
||||
css::uno::Reference<css::ucb::XUniversalContentBroker> xUcb(
|
||||
comphelper::getProcessServiceFactory()->createInstance(
|
||||
"com.sun.star.ucb.UniversalContentBroker"),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
css::uno::Sequence<css::uno::Any> aArgs{ css::uno::Any(OUString("NoConfig")) };
|
||||
css::uno::Reference<css::ucb::XContentProvider> xFileProvider(
|
||||
comphelper::getProcessServiceFactory()->createInstanceWithArguments(
|
||||
"com.sun.star.ucb.FileContentProvider", aArgs),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
xUcb->registerContentProvider(xFileProvider, "file", true);
|
||||
|
||||
// create and hold a reference to XToolkit here to avoid the lsan warning about its leak
|
||||
// due to getting created in the unusual case of no vcl main loop
|
||||
static css::uno::Reference<css::awt::XToolkit> xTk(
|
||||
comphelper::getProcessServiceFactory()->createInstance("com.sun.star.awt.Toolkit"),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
|
||||
if (__lsan_enable)
|
||||
__lsan_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
SvMemoryStream aStream(const_cast<uint8_t*>(data), size, StreamMode::READ);
|
||||
bool bRTFLoaded = TestPDFExportRTF(aStream);
|
||||
// if the rtf didn't load then reject so that input will not be added to the corpus
|
||||
// we're not interested in input that doesn't go on to exercise the pdf export
|
||||
return bRTFLoaded ? 0 : -1;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
@@ -0,0 +1,3 @@
|
||||
[libfuzzer]
|
||||
max_len = 512
|
||||
dict = rtf.dict
|
||||
Reference in New Issue
Block a user