summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaume Pujantell <jaume.pujantell@collabora.com>2023-03-03 19:25:11 +0100
committerAndras Timar <andras.timar@collabora.com>2023-03-07 20:52:23 +0000
commitda1d2ef7bb9de291941f1048b4012a730e159b2f (patch)
treefa0208a2f286ffb69fe37bcc669facb30ee4ca2b
parent5215f48c394ec8ed697be010e5a0493b77445e1d (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> (cherry picked from commit 574e89ccda1b389faca9f3e44d909a71b5599473) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148333 Tested-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r--vcl/qa/cppunit/filter/ipdf/data/array-mixed-numbers-and-elements.pdf55
-rw-r--r--vcl/qa/cppunit/filter/ipdf/ipdf.cxx25
-rw-r--r--vcl/source/filter/ipdf/pdfdocument.cxx45
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 93cc22360b56..32bd15643259 100644
--- a/vcl/qa/cppunit/filter/ipdf/ipdf.cxx
+++ b/vcl/qa/cppunit/filter/ipdf/ipdf.cxx
@@ -197,6 +197,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 7569deede0f5..8bc66d0c010d 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -3221,6 +3221,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);
@@ -3241,6 +3253,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);
@@ -3258,6 +3281,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);
@@ -3275,6 +3309,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);