Keep XRefStm pointer valid (because it may refer objects in streams which are not detected by uPDFParser) + Display max id in xref table and not object counts

This commit is contained in:
Grégory Soutadé 2022-03-12 21:11:47 +01:00
parent 03c18d225c
commit 00be31a318

View File

@ -862,8 +862,9 @@ namespace uPDFParser
::write(newFd, header, ret); ::write(newFd, header, ret);
int nbObjects = 1; int maxId = 0;
std::stringstream xref; std::stringstream xref;
off_t xrefStmOffset = 0;
xref << std::setfill('0'); xref << std::setfill('0');
xref << "xref\n"; xref << "xref\n";
@ -873,17 +874,31 @@ namespace uPDFParser
std::vector<Object*>::iterator it; std::vector<Object*>::iterator it;
for(it=_objects.begin(); it!=_objects.end(); it++) for(it=_objects.begin(); it!=_objects.end(); it++)
{ {
std::string objStr = (*it)->str(); Object* object = *it;
std::string objStr = object->str();
curOffset = lseek(newFd, 0, SEEK_CUR); curOffset = lseek(newFd, 0, SEEK_CUR);
::write(newFd, objStr.c_str(), objStr.size()); ::write(newFd, objStr.c_str(), objStr.size());
xref << std::setw(0) << (*it)->objectId() << " 1\n"; xref << std::setw(0) << object->objectId() << " 1\n";
xref << std::setw(10) << curOffset << " " << std::setw(5) << (*it)->generationNumber(); xref << std::setw(10) << curOffset << " " << std::setw(5) << object->generationNumber();
if ((*it)->used()) if (object->used())
xref << " n"; xref << " n";
else else
xref << " f" ; xref << " f" ;
xref << "\r\n" ; // Here \r seems important xref << "\r\n" ; // Here \r seems important
nbObjects++;
if (object->objectId() > maxId)
maxId = object->objectId();
if (object->hasKey("Type") && (*object)["Type"]->str() == "/XRef")
{
// Try to keep Prev link valid
if (object->hasKey("Prev") && xrefStmOffset != 0)
{
object->deleteKey("Prev");
object->dictionary().addData("Prev", new Integer(xrefStmOffset));
}
xrefStmOffset = curOffset;
}
} }
@ -894,9 +909,11 @@ namespace uPDFParser
trailer.deleteKey("Prev"); trailer.deleteKey("Prev");
trailer.deleteKey("Size"); trailer.deleteKey("Size");
trailer.dictionary().addData("Size", new Integer((int)nbObjects)); trailer.dictionary().addData("Size", new Integer(maxId+1));
trailer.deleteKey("XRefStm"); trailer.deleteKey("XRefStm");
if (xrefStmOffset != 0)
trailer.dictionary().addData("XRefStm", new Integer(xrefStmOffset));
std::string trailerStr = trailer.dictionary().str(); std::string trailerStr = trailer.dictionary().str();
::write(newFd, "trailer\n", 8); ::write(newFd, "trailer\n", 8);