summaryrefslogtreecommitdiff
path: root/vcl/source/filter/ipdf/pdfdocument.cxx
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-03-28 16:14:11 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-03-28 15:52:49 +0000
commit30608c66374f8effa9d534f7f9a22d41daa9770f (patch)
tree9298896890717507fe01cdaf4545775d5b1010ca /vcl/source/filter/ipdf/pdfdocument.cxx
parentb566f0d68804e97f9c73d1cc2beed568a4b74105 (diff)
tdf#106693 vcl PDF export, norefxobj: handle multiple refs in copied arrays
Also fix confusion about dictionaries in arrays and arrays in dictionaries. Change-Id: I0d71d5796b1eb4f89e3fd9a5b1f807d2a7340a35 Reviewed-on: https://gerrit.libreoffice.org/35806 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'vcl/source/filter/ipdf/pdfdocument.cxx')
-rw-r--r--vcl/source/filter/ipdf/pdfdocument.cxx34
1 files changed, 27 insertions, 7 deletions
diff --git a/vcl/source/filter/ipdf/pdfdocument.cxx b/vcl/source/filter/ipdf/pdfdocument.cxx
index 1c132353e0a6..86aeade27137 100644
--- a/vcl/source/filter/ipdf/pdfdocument.cxx
+++ b/vcl/source/filter/ipdf/pdfdocument.cxx
@@ -939,7 +939,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
}
case '[':
{
- auto pArr = new PDFArrayElement();
+ auto pArr = new PDFArrayElement(pObject);
rElements.push_back(std::unique_ptr<PDFElement>(pArr));
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{
@@ -963,9 +963,10 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
case ']':
{
rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndArrayElement()));
- pArray = nullptr;
- rStream.SeekRel(-1);
--nArrayDepth;
+ if (nArrayDepth == 0)
+ pArray = nullptr;
+ rStream.SeekRel(-1);
if (nDictionaryDepth == 0 && nArrayDepth == 0)
{
if (pObject)
@@ -2127,18 +2128,25 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
PDFArrayElement* pArray = nullptr;
sal_uInt64 nDictionaryOffset = 0;
int nDictionaryDepth = 0;
+ // Toplevel dictionary found (not inside an array).
+ bool bDictionaryFound = false;
+ // Toplevel array found (not inside a dictionary).
+ bool bArrayFound = false;
for (size_t i = nIndex; i < rElements.size(); ++i)
{
// Dictionary tokens can be nested, track enter/leave.
if (auto pDictionary = dynamic_cast<PDFDictionaryElement*>(rElements[i].get()))
{
+ bDictionaryFound = true;
if (++nDictionaryDepth == 1)
{
// First dictionary start, track start offset.
nDictionaryOffset = pDictionary->m_nLocation;
if (pThisObject)
{
- pThisObject->SetDictionary(pDictionary);
+ if (!bArrayFound)
+ // The the toplevel dictionary of the object.
+ pThisObject->SetDictionary(pDictionary);
pThisDictionary = pDictionary;
pThisObject->SetDictionaryOffset(nDictionaryOffset);
}
@@ -2189,7 +2197,11 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
else
{
if (pArray)
- pArray->PushBack(pName);
+ {
+ if (bDictionaryFound)
+ // Array inside dictionary.
+ pArray->PushBack(pName);
+ }
else
{
// Name-name key-value.
@@ -2208,6 +2220,7 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
auto pArr = dynamic_cast<PDFArrayElement*>(rElements[i].get());
if (pArr)
{
+ bArrayFound = true;
pArray = pArr;
continue;
}
@@ -2248,7 +2261,9 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
}
else
{
- pArray->PushBack(pReference);
+ if (bDictionaryFound)
+ // Array inside dictionary.
+ pArray->PushBack(pReference);
}
aNumbers.clear();
continue;
@@ -2932,7 +2947,10 @@ bool PDFEndObjectElement::Read(SvStream& /*rStream*/)
return true;
}
-PDFArrayElement::PDFArrayElement() = default;
+PDFArrayElement::PDFArrayElement(PDFObjectElement* pObject)
+ : m_pObject(pObject)
+{
+}
bool PDFArrayElement::Read(SvStream& rStream)
{
@@ -2952,6 +2970,8 @@ bool PDFArrayElement::Read(SvStream& rStream)
void PDFArrayElement::PushBack(PDFElement* pElement)
{
+ if (m_pObject)
+ SAL_INFO("vcl.filter", "PDFArrayElement::PushBack: object is " << m_pObject->GetObjectValue());
m_aElements.push_back(pElement);
}