xmlsecurity PDF verify: fix reading multiple subsections from an xref stream
This is especially needed, as we don't bother compressing updated objects into sections on signing, we simply use a separate section for each updated object. Work towards supporting xref streams and incremental updates at the same time. Change-Id: Ie9759edbba816991615fafc6602cdd440141b989
This commit is contained in:
@@ -1265,7 +1265,7 @@ bool PDFDocument::Read(SvStream& rStream)
|
||||
SAL_INFO("xmlsecurity.pdfio", "PDFDocument::Read: nStartXRef is " << nStartXRef);
|
||||
if (nStartXRef == 0)
|
||||
{
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Read: found no xref statrt offset");
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Read: found no xref start offset");
|
||||
return false;
|
||||
}
|
||||
while (true)
|
||||
@@ -1466,37 +1466,49 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
|
||||
|
||||
// Look up the first and the last entry we need to read.
|
||||
auto pIndex = dynamic_cast<PDFArrayElement*>(pObject->Lookup("Index"));
|
||||
size_t nFirstObject = 0;
|
||||
size_t nNumberOfObjects = 0;
|
||||
if (!pIndex || pIndex->GetElements().size() < 2)
|
||||
std::vector<size_t> aFirstObjects;
|
||||
std::vector<size_t> aNumberOfObjects;
|
||||
if (!pIndex)
|
||||
{
|
||||
auto pSize = dynamic_cast<PDFNumberElement*>(pObject->Lookup("Size"));
|
||||
if (pSize)
|
||||
nNumberOfObjects = pSize->GetValue();
|
||||
{
|
||||
aFirstObjects.push_back(0);
|
||||
aNumberOfObjects.push_back(pSize->GetValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: Index not found or has < 2 elements");
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: Index and Size not found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::vector<PDFElement*>& rIndexElements = pIndex->GetElements();
|
||||
auto pFirstObject = dynamic_cast<PDFNumberElement*>(rIndexElements[0]);
|
||||
size_t nFirstObject = 0;
|
||||
for (size_t i = 0; i < rIndexElements.size(); ++i)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
auto pFirstObject = dynamic_cast<PDFNumberElement*>(rIndexElements[i]);
|
||||
if (!pFirstObject)
|
||||
{
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: Index has no first object");
|
||||
return;
|
||||
}
|
||||
nFirstObject = pFirstObject->GetValue();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto pNumberOfObjects = dynamic_cast<PDFNumberElement*>(rIndexElements[1]);
|
||||
auto pNumberOfObjects = dynamic_cast<PDFNumberElement*>(rIndexElements[i]);
|
||||
if (!pNumberOfObjects)
|
||||
{
|
||||
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: Index has no number of objects");
|
||||
return;
|
||||
}
|
||||
nNumberOfObjects = pNumberOfObjects->GetValue();
|
||||
aFirstObjects.push_back(nFirstObject);
|
||||
aNumberOfObjects.push_back(pNumberOfObjects->GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the format of a single entry.
|
||||
@@ -1529,6 +1541,11 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
|
||||
}
|
||||
|
||||
aStream.Seek(0);
|
||||
for (size_t nSubSection = 0; nSubSection < aFirstObjects.size(); ++nSubSection)
|
||||
{
|
||||
size_t nFirstObject = aFirstObjects[nSubSection];
|
||||
size_t nNumberOfObjects = aNumberOfObjects[nSubSection];
|
||||
|
||||
// This is the line as read from the stream.
|
||||
std::vector<unsigned char> aOrigLine(nLineLength);
|
||||
// This is the line as it appears after tweaking according to nPredictor.
|
||||
@@ -1616,6 +1633,7 @@ void PDFDocument::ReadXRefStream(SvStream& rStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDocument::ReadXRef(SvStream& rStream)
|
||||
{
|
||||
|
Reference in New Issue
Block a user