diff options
author | Jaume Pujantell <jaume.pujantell@collabora.com> | 2023-03-03 19:25:11 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2023-03-07 08:36:01 +0000 |
commit | 574e89ccda1b389faca9f3e44d909a71b5599473 (patch) | |
tree | 5f88ba089f096f461dafdd6149ec6557b28ee465 /vcl | |
parent | 5a41b0a42acac80d7c601f0899c82b9f390bff3d (diff) |
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.timar@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf | 55 | ||||
-rw-r--r-- | vcl/qa/cppunit/filter/ipdf/ipdf.cxx | 25 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfdocument.cxx | 45 |
3 files changed, 125 insertions, 0 deletions
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 1c143a1b8319..c27555ca1d70 100644 --- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx +++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx @@ -186,6 +186,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 = createFileURL(u"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 19748e241ead..5ff50d3b55ac 100644 --- a/vcl/source/filter/ipdf/pdfdocument.cxx +++ b/vcl/source/filter/ipdf/pdfdocument.cxx @@ -3248,6 +3248,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); @@ -3268,6 +3280,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); @@ -3285,6 +3308,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); @@ -3302,6 +3336,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); |