vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 38 ++++++++++++++++++++++++++ vcl/source/filter/ipdf/pdfdocument.cxx | 21 +++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-)
New commits: commit 9a45d2779ceaa1938feddf820d826922ed17854b Author: Dennis Francis <[email protected]> AuthorDate: Thu Dec 1 11:18:22 2022 +0530 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Dec 21 07:58:38 2022 +0000 vcl: read references to /Kids array... if the argument of /Kids is not an array. Conflicts: vcl/qa/cppunit/pdfexport/pdfexport.cxx Change-Id: Ib73962d3a27aa7e1ce5ddbe6845a1dd73bd7a343 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143559 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 10185a6aec5d3b74a51e4b9474645e12bf794df8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144434 Tested-by: Jenkins diff --git a/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf b/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf new file mode 100644 index 000000000000..598358a636aa Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index ea8f83e6ba8f..f18077505abd 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -15,6 +15,7 @@ #include <config_features.h> #include <config_fonts.h> +#include <osl/process.h> #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XStorable.hpp> @@ -4098,6 +4099,43 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf139627) / aRect[jehtatweel].getWidth()); #endif } + +CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportRefToKids) +{ + // We need to enable PDFium import (and make sure to disable after the test) + bool bResetEnvVar = false; + if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr) + { + bResetEnvVar = true; + osl_setEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData, OUString("1").pData); + } + comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() { + if (bResetEnvVar) + osl_clearEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData); + }); + + // Load the PDF and save as PDF + vcl::filter::PDFDocument aDocument; + load(u"ref-to-kids.pdf", aDocument); + + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(size_t(5), aPages.size()); + + vcl::filter::PDFObjectElement* pResources = aPages[0]->LookupObject("Resources"); + CPPUNIT_ASSERT(pResources); + + auto pXObjects + = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pResources->Lookup("XObject")); + CPPUNIT_ASSERT(pXObjects); + + // Without the fix LookupObject for all /Im's will fail. + for (auto const& rPair : pXObjects->GetItems()) + { + if (rPair.first.startsWith("Im")) + CPPUNIT_ASSERT(pXObjects->LookupObject(rPair.first)); + } +} + } // end anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index 25e731f5352a..19748e241ead 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -1918,7 +1918,26 @@ const std::vector<std::unique_ptr<PDFElement>>& PDFDocument::GetElements() const /// Visits the page tree recursively, looking for page objects. static void visitPages(PDFObjectElement* pPages, std::vector<PDFObjectElement*>& rRet) { - auto pKids = dynamic_cast<PDFArrayElement*>(pPages->Lookup("Kids")); + auto pKidsRef = pPages->Lookup("Kids"); + auto pKids = dynamic_cast<PDFArrayElement*>(pKidsRef); + if (!pKids) + { + auto pRefKids = dynamic_cast<PDFReferenceElement*>(pKidsRef); + if (!pRefKids) + { + SAL_WARN("vcl.filter", "visitPages: pages has no kids"); + return; + } + auto pObjWithKids = pRefKids->LookupObject(); + if (!pObjWithKids) + { + SAL_WARN("vcl.filter", "visitPages: pages has no kids"); + return; + } + + pKids = pObjWithKids->GetArray(); + } + if (!pKids) { SAL_WARN("vcl.filter", "visitPages: pages has no kids");
