From 47aa71cf39764135f3e3a39cbfb8efc50de1ac28 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 12 May 2017 23:38:26 +0200 Subject: Make Dict incRef/decRef private --- poppler/Catalog.cc | 40 +++++++++++----------------------------- poppler/Catalog.h | 2 +- poppler/Dict.h | 9 +++++---- poppler/PDFDoc.cc | 37 ++++++++++++++++--------------------- poppler/PDFDoc.h | 7 +++---- poppler/Page.cc | 17 ++++++++--------- poppler/Page.h | 2 +- utils/pdfunite.cc | 12 +++++------- 8 files changed, 50 insertions(+), 76 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 8ffff9dc..6c820c66 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -148,15 +148,7 @@ Catalog::~Catalog() { delete attrsList; } delete pagesRefList; - if (pagesList) { - std::vector::iterator it; - for (it = pagesList->begin() ; it != pagesList->end(); ++it ) { - if (!(*it)->decRef()) { - delete *it; - } - } - delete pagesList; - } + delete pagesList; if (pages) { for (int i = 0; i < pagesSize; ++i) { if (pages[i]) { @@ -238,8 +230,6 @@ Ref *Catalog::getPageRef(int i) GBool Catalog::cachePageTree(int page) { - Dict *pagesDict; - if (pagesList == NULL) { Ref pagesRef; @@ -264,10 +254,7 @@ GBool Catalog::cachePageTree(int page) Object obj = catDict.dictLookup("Pages"); // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. - if (obj.isDict()) { - obj.getDict()->incRef(); - pagesDict = obj.getDict(); - } else { + if (!obj.isDict()) { error(errSyntaxError, -1, "Top-level pages object is wrong type ({0:s})", obj.getTypeName()); return gFalse; } @@ -277,7 +264,6 @@ GBool Catalog::cachePageTree(int page) pageRefs = (Ref *)gmallocn_checkoverflow(pagesSize, sizeof(Ref)); if (pages == NULL || pageRefs == NULL ) { error(errSyntaxError, -1, "Cannot allocate page cache"); - pagesDict->decRef(); pagesSize = 0; return gFalse; } @@ -287,12 +273,12 @@ GBool Catalog::cachePageTree(int page) pageRefs[i].gen = -1; } - pagesList = new std::vector(); - pagesList->push_back(pagesDict); + attrsList = new std::vector(); + attrsList->push_back(new PageAttrs(NULL, obj.getDict())); + pagesList = new std::vector(); + pagesList->push_back(std::move(obj)); pagesRefList = new std::vector(); pagesRefList->push_back(pagesRef); - attrsList = new std::vector(); - attrsList->push_back(new PageAttrs(NULL, pagesDict)); kidsIdxList = new std::vector(); kidsIdxList->push_back(0); lastCachedPage = 0; @@ -305,8 +291,8 @@ GBool Catalog::cachePageTree(int page) if (pagesList->empty()) return gFalse; - pagesDict = pagesList->back(); - Object kids = pagesDict->lookup("Kids"); + Object pagesDict = pagesList->back().copy(); + Object kids = pagesDict.dictLookup("Kids"); if (!kids.isArray()) { error(errSyntaxError, -1, "Kids object (page {0:d}) is wrong type ({1:s})", lastCachedPage+1, kids.getTypeName()); @@ -315,9 +301,6 @@ GBool Catalog::cachePageTree(int page) int kidsIdx = kidsIdxList->back(); if (kidsIdx >= kids.arrayGetLength()) { - if (!pagesList->back()->decRef()) { - delete pagesList->back(); - } pagesList->pop_back(); pagesRefList->pop_back(); delete attrsList->back(); @@ -350,7 +333,7 @@ GBool Catalog::cachePageTree(int page) Object kid = kids.arrayGet(kidsIdx); if (kid.isDict("Page") || (kid.isDict() && !kid.getDict()->hasKey("Kids"))) { PageAttrs *attrs = new PageAttrs(attrsList->back(), kid.getDict()); - Page *p = new Page(doc, lastCachedPage+1, kid.getDict(), + Page *p = new Page(doc, lastCachedPage+1, &kid, kidRef.getRef(), attrs, form); if (!p->isOk()) { error(errSyntaxError, -1, "Failed to create page (page {0:d})", lastCachedPage+1); @@ -375,8 +358,7 @@ GBool Catalog::cachePageTree(int page) } else if (kid.isDict()) { attrsList->push_back(new PageAttrs(attrsList->back(), kid.getDict())); pagesRefList->push_back(kidRef.getRef()); - kid.getDict()->incRef(); - pagesList->push_back(kid.getDict()); + pagesList->push_back(std::move(kid)); kidsIdxList->push_back(0); } else { error(errSyntaxError, -1, "Kid object (page {0:d}) is wrong type ({1:s})", @@ -792,7 +774,7 @@ int Catalog::getNumPages() Dict *pageDict = pagesDict.getDict(); if (pageRootRef.isRef()) { const Ref pageRef = pageRootRef.getRef(); - Page *p = new Page(doc, 1, pageDict, pageRef, new PageAttrs(NULL, pageDict), form); + Page *p = new Page(doc, 1, &pagesDict, pageRef, new PageAttrs(NULL, pageDict), form); if (p->isOk()) { pages = (Page **)gmallocn(1, sizeof(Page *)); pageRefs = (Ref *)gmallocn(1, sizeof(Ref)); diff --git a/poppler/Catalog.h b/poppler/Catalog.h index eb324b78..c8b501a1 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -248,7 +248,7 @@ private: Page **pages; // array of pages Ref *pageRefs; // object ID for each page int lastCachedPage; - std::vector *pagesList; + std::vector *pagesList; std::vector *pagesRefList; std::vector *attrsList; std::vector *kidsIdxList; diff --git a/poppler/Dict.h b/poppler/Dict.h index 0e65bfed..b775a574 100644 --- a/poppler/Dict.h +++ b/poppler/Dict.h @@ -56,10 +56,6 @@ public: // Destructor. ~Dict(); - // Reference counting. - int incRef(); - int decRef(); - // Get number of entries. int getLength() { return length; } @@ -97,6 +93,11 @@ public: GBool hasKey(const char *key); private: + friend class Object; // for incRef/decRef + + // Reference counting. + int incRef(); + int decRef(); GBool sorted; XRef *xref; // the xref table for this PDF file diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 16981b93..206b7e42 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -861,11 +861,10 @@ int PDFDoc::savePageAs(GooString *name, int pageNo) Ref ref; ref.num = rootNum; ref.gen = 0; - Dict *trailerDict = createTrailerDict(rootNum + 3, gFalse, 0, &ref, getXRef(), + Object trailerDict = createTrailerDict(rootNum + 3, gFalse, 0, &ref, getXRef(), name->getCString(), uxrefOffset); - writeXRefTableTrailer(trailerDict, yRef, gFalse /* do not write unnecessary entries */, + writeXRefTableTrailer(std::move(trailerDict), yRef, gFalse /* do not write unnecessary entries */, uxrefOffset, outStr, getXRef()); - delete trailerDict; outStr->close(); fclose(f); @@ -1004,14 +1003,13 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr) uxref->add(uxrefStreamRef.num, uxrefStreamRef.gen, uxrefOffset, gTrue); } - Dict *trailerDict = createTrailerDict(numobjects, gTrue, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset); + Object trailerDict = createTrailerDict(numobjects, gTrue, getStartXRef(), &rootRef, getXRef(), fileNameA, uxrefOffset); if (xRefStream) { - writeXRefStreamTrailer(trailerDict, uxref, &uxrefStreamRef, uxrefOffset, outStr, getXRef()); + writeXRefStreamTrailer(std::move(trailerDict), uxref, &uxrefStreamRef, uxrefOffset, outStr, getXRef()); } else { - writeXRefTableTrailer(trailerDict, uxref, gFalse, uxrefOffset, outStr, getXRef()); + writeXRefTableTrailer(std::move(trailerDict), uxref, gFalse, uxrefOffset, outStr, getXRef()); } - delete trailerDict; delete uxref; } @@ -1340,7 +1338,7 @@ void PDFDoc::writeObjectFooter (OutStream* outStr) outStr->printf("endobj\r\n"); } -Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxRef, +Object PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxRef, Ref *root, XRef *xRef, const char *fileName, Goffset fileSize) { Dict *trailerDict = new Dict(xRef); @@ -1421,29 +1419,28 @@ Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Goffset startxR } } - return trailerDict; + return Object(trailerDict); } -void PDFDoc::writeXRefTableTrailer(Dict *trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) +void PDFDoc::writeXRefTableTrailer(Object &&trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) { uxref->writeTableToFile( outStr, writeAllEntries ); outStr->printf( "trailer\r\n"); - writeDictionnary(trailerDict, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0); + writeDictionnary(trailerDict.getDict(), outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0); outStr->printf( "\r\nstartxref\r\n"); outStr->printf( "%lli\r\n", uxrefOffset); outStr->printf( "%%%%EOF\r\n"); } -void PDFDoc::writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) +void PDFDoc::writeXRefStreamTrailer (Object &&trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) { GooString stmData; // Fill stmData and some trailerDict fields - uxref->writeStreamToBuffer(&stmData, trailerDict, xRef); + uxref->writeStreamToBuffer(&stmData, trailerDict.getDict(), xRef); // Create XRef stream object and write it - trailerDict->incRef(); - MemStream *mStream = new MemStream( stmData.getCString(), 0, stmData.getLength(), Object(trailerDict) ); + MemStream *mStream = new MemStream( stmData.getCString(), 0, stmData.getLength(), std::move(trailerDict) ); writeObjectHeader(uxrefStreamRef, outStr); Object obj1(static_cast(mStream)); writeObject(&obj1, outStr, xRef, 0, NULL, cryptRC4, 0, 0, 0); @@ -1469,10 +1466,9 @@ void PDFDoc::writeXRefTableTrailer(Goffset uxrefOffset, XRef *uxref, GBool write Ref ref; ref.num = getXRef()->getRootNum(); ref.gen = getXRef()->getRootGen(); - Dict * trailerDict = createTrailerDict(uxrefSize, incrUpdate, getStartXRef(), &ref, + Object trailerDict = createTrailerDict(uxrefSize, incrUpdate, getStartXRef(), &ref, getXRef(), fileNameA, fileSize); - writeXRefTableTrailer(trailerDict, uxref, writeAllEntries, uxrefOffset, outStr, getXRef()); - delete trailerDict; + writeXRefTableTrailer(std::move(trailerDict), uxref, writeAllEntries, uxrefOffset, outStr, getXRef()); } void PDFDoc::writeHeader(OutStream *outStr, int major, int minor) @@ -1890,7 +1886,6 @@ int PDFDoc::getNumPages() Page *PDFDoc::parsePage(int page) { Ref pageRef; - Dict *pageDict; pageRef.num = getHints()->getPageObjectNum(page); if (!pageRef.num) { @@ -1910,9 +1905,9 @@ Page *PDFDoc::parsePage(int page) error(errSyntaxWarning, -1, "Object ({0:d} {1:d}) is not a pageDict", pageRef.num, pageRef.gen); return NULL; } - pageDict = obj.getDict(); + Dict *pageDict = obj.getDict(); - return new Page(this, page, pageDict, pageRef, + return new Page(this, page, &obj, pageRef, new PageAttrs(NULL, pageDict), catalog->getForm()); } diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 2c703b14..6a83c7c5 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -301,12 +301,11 @@ public: CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen); static void writeHeader(OutStream *outStr, int major, int minor); - // Ownership goes to the caller - static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef, + static Object createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef, Ref *root, XRef *xRef, const char *fileName, Goffset fileSize); - static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries, + static void writeXRefTableTrailer (Object &&trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef); - static void writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, + static void writeXRefStreamTrailer (Object &&trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef); private: diff --git a/poppler/Page.cc b/poppler/Page.cc index b8002023..197e2bef 100644 --- a/poppler/Page.cc +++ b/poppler/Page.cc @@ -248,7 +248,7 @@ GBool PageAttrs::readBox(Dict *dict, const char *key, PDFRectangle *box) { // Page //------------------------------------------------------------------------ -Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrsA, Form *form) { +Page::Page(PDFDoc *docA, int numA, Object *pageDict, Ref pageRefA, PageAttrs *attrsA, Form *form) { #if MULTITHREADED gInitMutex(&mutex); #endif @@ -259,8 +259,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr duration = -1; annots = NULL; - pageDict->incRef(); - pageObj = Object(pageDict); + pageObj = pageDict->copy(); pageRef = pageRefA; // get attributes @@ -268,7 +267,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr attrs->clipBoxes(); // transtion - trans = pageDict->lookupNF("Trans"); + trans = pageDict->dictLookupNF("Trans"); if (!(trans.isRef() || trans.isDict() || trans.isNull())) { error(errSyntaxError, -1, "Page transition object (page {0:d}) is wrong type ({1:s})", num, trans.getTypeName()); @@ -276,7 +275,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr } // duration - Object tmp = pageDict->lookupNF("Dur"); + Object tmp = pageDict->dictLookupNF("Dur"); if (!(tmp.isNum() || tmp.isNull())) { error(errSyntaxError, -1, "Page duration object (page {0:d}) is wrong type ({1:s})", num, tmp.getTypeName()); @@ -285,7 +284,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr } // annotations - annotsObj = pageDict->lookupNF("Annots"); + annotsObj = pageDict->dictLookupNF("Annots"); if (!(annotsObj.isRef() || annotsObj.isArray() || annotsObj.isNull())) { error(errSyntaxError, -1, "Page annotations object (page {0:d}) is wrong type ({1:s})", num, annotsObj.getTypeName()); @@ -293,7 +292,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr } // contents - contents = pageDict->lookupNF("Contents"); + contents = pageDict->dictLookupNF("Contents"); if (!(contents.isRef() || contents.isArray() || contents.isNull())) { error(errSyntaxError, -1, "Page contents object (page {0:d}) is wrong type ({1:s})", @@ -302,7 +301,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr } // thumb - thumb = pageDict->lookupNF("Thumb"); + thumb = pageDict->dictLookupNF("Thumb"); if (!(thumb.isStream() || thumb.isNull() || thumb.isRef())) { error(errSyntaxError, -1, "Page thumb object (page {0:d}) is wrong type ({1:s})", num, thumb.getTypeName()); @@ -310,7 +309,7 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attr } // actions - actions = pageDict->lookupNF("AA"); + actions = pageDict->dictLookupNF("AA"); if (!(actions.isDict() || actions.isNull())) { error(errSyntaxError, -1, "Page additional action object (page {0:d}) is wrong type ({1:s})", num, actions.getTypeName()); diff --git a/poppler/Page.h b/poppler/Page.h index e548c867..2a597131 100644 --- a/poppler/Page.h +++ b/poppler/Page.h @@ -143,7 +143,7 @@ class Page { public: // Constructor. - Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrsA, Form *form); + Page(PDFDoc *docA, int numA, Object *pageDict, Ref pageRefA, PageAttrs *attrsA, Form *form); // Destructor. ~Page(); diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc index 55615e01..dd563857 100644 --- a/utils/pdfunite.cc +++ b/utils/pdfunite.cc @@ -283,10 +283,9 @@ int main (int argc, char *argv[]) Ref *refPage = docs[i]->getCatalog()->getPageRef(j); Object page = docs[i]->getXRef()->fetch(refPage->num, refPage->gen); Dict *pageDict = page.getDict(); - Dict *resDict = docs[i]->getCatalog()->getPage(j)->getResourceDict(); - if (resDict) { - resDict->incRef(); - pageDict->set("Resources", Object(resDict)); + Object *resDict = docs[i]->getCatalog()->getPage(j)->getResourceDictObject(); + if (resDict->isDict()) { + pageDict->set("Resources", resDict->copy()); } pages.push_back(std::move(page)); offsets.push_back(numOffset); @@ -382,11 +381,10 @@ int main (int argc, char *argv[]) Ref ref; ref.num = rootNum; ref.gen = 0; - Dict *trailerDict = PDFDoc::createTrailerDict(objectsCount, gFalse, 0, &ref, yRef, + Object trailerDict = PDFDoc::createTrailerDict(objectsCount, gFalse, 0, &ref, yRef, fileName, outStr->getPos()); - PDFDoc::writeXRefTableTrailer(trailerDict, yRef, gTrue, // write all entries according to ISO 32000-1, 7.5.4 Cross-Reference Table: "For a file that has never been incrementally updated, the cross-reference section shall contain only one subsection, whose object numbering begins at 0." + PDFDoc::writeXRefTableTrailer(std::move(trailerDict), yRef, gTrue, // write all entries according to ISO 32000-1, 7.5.4 Cross-Reference Table: "For a file that has never been incrementally updated, the cross-reference section shall contain only one subsection, whose object numbering begins at 0." uxrefOffset, outStr, yRef); - delete trailerDict; outStr->close(); delete outStr; -- cgit v1.2.3