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:
Caolán McNamara
2024-09-25 22:28:32 +02:00
parent 747e2676ec
commit 7198c5e49e
10 changed files with 250 additions and 8 deletions
+1
View File
@@ -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) \
+1
View File
@@ -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
View File
@@ -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;
+114
View File
@@ -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: */
+7 -7
View File
@@ -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;
+50
View File
@@ -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:
+1
View File
@@ -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 \
+10
View File
@@ -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);
+62
View File
@@ -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: */
+3
View File
@@ -0,0 +1,3 @@
[libfuzzer]
max_len = 512
dict = rtf.dict