xmlsecurity PDF verify: handle multiple startxref in the last 1024 bytes

Usually this is not a problem, but it's easy to construct a document
manually that contains multiple startxref tokens at the last 1024 bytes.
Make sure we read the last of those, not the first one.

This is triggered by an upcoming unit test for tdf#106059.

Change-Id: I94fbb5d407c4a03b7c2c6e207200127bb374e750
Reviewed-on: https://gerrit.libreoffice.org/34607
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
This commit is contained in:
Miklos Vajna 2017-02-24 11:47:40 +01:00
parent b61a2db728
commit 7737457558

View file

@ -1404,14 +1404,27 @@ size_t PDFDocument::FindStartXRef(SvStream& rStream)
if (nSize != aBuf.size())
aBuf.resize(nSize);
OString aPrefix("startxref");
auto it = std::search(aBuf.begin(), aBuf.end(), aPrefix.getStr(), aPrefix.getStr() + aPrefix.getLength());
if (it == aBuf.end())
// Find the last startxref at the end of the document.
std::vector<char>::iterator itLastValid = aBuf.end();
std::vector<char>::iterator it = aBuf.begin();
while (true)
{
it = std::search(it, aBuf.end(), aPrefix.getStr(), aPrefix.getStr() + aPrefix.getLength());
if (it == aBuf.end())
break;
else
{
itLastValid = it;
++it;
}
}
if (itLastValid == aBuf.end())
{
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::FindStartXRef: found no startxref");
return 0;
}
rStream.SeekRel(it - aBuf.begin() + aPrefix.getLength());
rStream.SeekRel(itLastValid - aBuf.begin() + aPrefix.getLength());
if (rStream.IsEof())
{
SAL_WARN("xmlsecurity.pdfio", "PDFDocument::FindStartXRef: unexpected end of stream after startxref");