vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf | 55 ++++++++++ vcl/qa/cppunit/filter/ipdf/ipdf.cxx | 25 ++++ vcl/source/filter/ipdf/pdfdocument.cxx | 45 ++++++++ 3 files changed, 125 insertions(+)
New commits: commit b4c912f680bb195ca17a506ed3037c588144a423 Author: Jaume Pujantell <jaume.pujant...@collabora.com> AuthorDate: Fri Mar 3 19:25:11 2023 +0100 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Tue Mar 7 22:44:58 2023 +0000 Fix a bug parsing pdf arrays The parser ignored number elements in some situations, like before a reference element. This manifested in creating an invalid pdf file when exporting as pdf a document that contains a pdf. Change-Id: I98625c8da8631056079814f7e824f36177cf41c7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148198 Tested-by: Jenkins Reviewed-by: Andras Timar <andras.ti...@collabora.com> (cherry picked from commit 574e89ccda1b389faca9f3e44d909a71b5599473) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148332 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf b/vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf new file mode 100644 index 000000000000..01030ecf88bc --- /dev/null +++ b/vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf @@ -0,0 +1,55 @@ +%PDF-1.7 +%��� +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [0 0 200 300] + /Count 1 + /Kids [3 0 R] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Contents 4 0 R + /Test [1 4 0 R 3 false 5 (Lieral) 7 <90>] +>> +endobj +4 0 obj << + /Length 188 +>> +stream +q +0 0 0 rg +0 290 10 10 re B* +10 150 50 30 re B* +0 0 1 rg +190 290 10 10 re B* +70 232 50 30 re B* +0 1 0 rg +190 0 10 10 re B* +130 150 50 30 re B* +1 0 0 rg +0 0 10 10 re B* +70 67 50 30 re B* +Q +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000157 00000 n +0000000270 00000 n +trailer << + /Root 1 0 R + /Size 5 +>> +startxref +510 +%%EOF diff --git a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx index 2de6cd4889d5..9077e6ba5d45 100644 --- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx +++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx @@ -201,6 +201,31 @@ CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testCommentEnd) CPPUNIT_ASSERT(aDocument.Read(aFile)); } +CPPUNIT_TEST_FIXTURE(VclFilterIpdfTest, testMixedArrayWithNumbers) +{ + // Load a file that has markup like this: + // 3 0 obj << + // /Test [1 4 0 R 3 false 5 (Lieral) 7 <90>] + // >> + OUString aSourceURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "array-mixed-numbers-and-elements.pdf"; + SvFileStream aFile(aSourceURL, StreamMode::READ); + vcl::filter::PDFDocument aDocument; + CPPUNIT_ASSERT(aDocument.Read(aFile)); + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT(!aPages.empty()); + vcl::filter::PDFObjectElement* pPage = aPages[0]; + auto pTest = dynamic_cast<vcl::filter::PDFArrayElement*>(pPage->Lookup("Test")); + std::vector<vcl::filter::PDFElement*> aElements = pTest->GetElements(); + + // Without the accompanying fix in place, this test would have failed with + // the array containing the wrong number of elements and in the incorrect order + CPPUNIT_ASSERT_EQUAL(8, static_cast<int>(aElements.size())); + CPPUNIT_ASSERT(dynamic_cast<vcl::filter::PDFNumberElement*>(aElements[0])); + CPPUNIT_ASSERT(dynamic_cast<vcl::filter::PDFNumberElement*>(aElements[2])); + CPPUNIT_ASSERT(dynamic_cast<vcl::filter::PDFNumberElement*>(aElements[4])); + CPPUNIT_ASSERT(dynamic_cast<vcl::filter::PDFNumberElement*>(aElements[6])); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx index 9ef202ee132b..c8882a6a709b 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -3247,6 +3247,18 @@ size_t PDFObjectParser::parse(PDFElement* pParsingElement, size_t nStartIndex, i } else if (auto pReference = dynamic_cast<PDFReferenceElement*>(pCurrentElement)) { + // Handle previously stored number + if (aNumbers.size() > 2) + { + aNumbers.resize(aNumbers.size() - 2); + if (pParsingArray) + { + for (auto& pNumber : aNumbers) + pParsingArray->PushBack(pNumber); + } + aNumbers.clear(); + } + if (pParsingArray) { pParsingArray->PushBack(pReference); @@ -3267,6 +3279,17 @@ size_t PDFObjectParser::parse(PDFElement* pParsingElement, size_t nStartIndex, i } else if (auto pLiteralString = dynamic_cast<PDFLiteralStringElement*>(pCurrentElement)) { + // Handle previously stored number + if (!aNumbers.empty()) + { + if (pParsingArray) + { + for (auto& pNumber : aNumbers) + pParsingArray->PushBack(pNumber); + } + aNumbers.clear(); + } + if (pParsingArray) { pParsingArray->PushBack(pLiteralString); @@ -3284,6 +3307,17 @@ size_t PDFObjectParser::parse(PDFElement* pParsingElement, size_t nStartIndex, i } else if (auto pBoolean = dynamic_cast<PDFBooleanElement*>(pCurrentElement)) { + // Handle previously stored number + if (!aNumbers.empty()) + { + if (pParsingArray) + { + for (auto& pNumber : aNumbers) + pParsingArray->PushBack(pNumber); + } + aNumbers.clear(); + } + if (pParsingArray) { pParsingArray->PushBack(pBoolean); @@ -3301,6 +3335,17 @@ size_t PDFObjectParser::parse(PDFElement* pParsingElement, size_t nStartIndex, i } else if (auto pHexString = dynamic_cast<PDFHexStringElement*>(pCurrentElement)) { + // Handle previously stored number + if (!aNumbers.empty()) + { + if (pParsingArray) + { + for (auto& pNumber : aNumbers) + pParsingArray->PushBack(pNumber); + } + aNumbers.clear(); + } + if (pParsingArray) { pParsingArray->PushBack(pHexString);