summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2017-05-05 23:32:32 +0200
committerAlbert Astals Cid <aacid@kde.org>2017-05-05 23:32:32 +0200
commit3c29ded4bee5eadb829ed46af2ec92be57b0077b (patch)
treee9a549c6258b4303fbb97a8bfda8ca76a45866e1
parentd73bcd3721f3b53bb97241cc53a6abf807aff782 (diff)
Make Object free itself on init and destruction
Will make for a *much* easier way to code. Patches with more std::move coming on top. Most things seem to work though i'm pretty sure some things are broken. NEEDS TESTING
-rw-r--r--poppler/Annot.cc3
-rw-r--r--poppler/Array.cc5
-rw-r--r--poppler/Array.h4
-rw-r--r--poppler/Catalog.cc29
-rw-r--r--poppler/Catalog.h6
-rw-r--r--poppler/DCTStream.cc8
-rw-r--r--poppler/DCTStream.h4
-rw-r--r--poppler/Dict.cc29
-rw-r--r--poppler/Dict.h4
-rw-r--r--poppler/Form.cc1
-rw-r--r--poppler/Gfx.cc25
-rw-r--r--poppler/Movie.cc30
-rw-r--r--poppler/Movie.h2
-rw-r--r--poppler/Object.cc51
-rw-r--r--poppler/Object.h79
-rw-r--r--poppler/OptionalContent.cc2
-rw-r--r--poppler/Page.cc4
-rw-r--r--poppler/Page.h6
-rw-r--r--poppler/Parser.cc4
-rw-r--r--poppler/Stream.cc36
-rw-r--r--poppler/Stream.h8
-rw-r--r--poppler/StructElement.cc10
-rw-r--r--poppler/XRef.cc19
-rw-r--r--utils/pdfunite.cc4
24 files changed, 234 insertions, 139 deletions
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 279f650d..73c2fe66 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2971,9 +2971,10 @@ static GfxFont * createAnnotDrawFont(XRef * xref, Object *fontResDict)
fontsDictObj.initDict(fontsDict);
Dict *dict = new Dict(xref);
+ dict->decRef();
dict->add(copyString("Font"), &fontsDictObj);
-
fontResDict->initDict(dict);
+
return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict);
}
diff --git a/poppler/Array.cc b/poppler/Array.cc
index 230c3287..131e4133 100644
--- a/poppler/Array.cc
+++ b/poppler/Array.cc
@@ -16,7 +16,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
-// Copyright (C) 2013 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2013, 2017 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -97,7 +97,8 @@ void Array::add(Object *elem) {
}
elems = (Object *)greallocn(elems, size, sizeof(Object));
}
- elems[length] = *elem;
+ elems[length].initNullNoFree();
+ elem->shallowCopy(&elems[length]);
++length;
}
diff --git a/poppler/Array.h b/poppler/Array.h
index e78e399b..6240295a 100644
--- a/poppler/Array.h
+++ b/poppler/Array.h
@@ -16,6 +16,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
+// Copyright (C) 2017 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -58,7 +59,8 @@ public:
// Copy array with new xref
Object *copy(XRef *xrefA, Object *obj);
- // Add an element.
+ // Add an element
+ // elem becomes a dead object after this call
void add(Object *elem);
// Remove an element by position
diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc
index 0e37c843..c415c7f5 100644
--- a/poppler/Catalog.cc
+++ b/poppler/Catalog.cc
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
-// Copyright (C) 2005-2013, 2015 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2005-2013, 2015, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Jeff Muizelaar <jrmuizel@nit.ca>
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
@@ -548,7 +548,10 @@ LinkDest *Catalog::getDestNameTreeDest(int i)
Object obj;
catalogLocker();
- getDestNameTree()->getValue(i).fetch(xref, &obj);
+ Object *aux = getDestNameTree()->getValue(i);
+ if (aux) {
+ aux->fetch(xref, &obj);
+ }
dest = createLinkDest(&obj);
obj.free();
@@ -558,16 +561,15 @@ LinkDest *Catalog::getDestNameTreeDest(int i)
FileSpec *Catalog::embeddedFile(int i)
{
Object efDict;
- Object obj;
catalogLocker();
- obj = getEmbeddedFileNameTree()->getValue(i);
+ Object *obj = getEmbeddedFileNameTree()->getValue(i);
FileSpec *embeddedFile = 0;
- if (obj.isRef()) {
+ if (obj->isRef()) {
Object fsDict;
- embeddedFile = new FileSpec(obj.fetch(xref, &fsDict));
+ embeddedFile = new FileSpec(obj->fetch(xref, &fsDict));
fsDict.free();
- } else if (obj.isDict()) {
- embeddedFile = new FileSpec(&obj);
+ } else if (obj->isDict()) {
+ embeddedFile = new FileSpec(obj);
} else {
Object null;
embeddedFile = new FileSpec(&null);
@@ -581,7 +583,10 @@ GooString *Catalog::getJS(int i)
// getJSNameTree()->getValue(i) returns a shallow copy of the object so we
// do not need to free it
catalogLocker();
- getJSNameTree()->getValue(i).fetch(xref, &obj);
+ Object *aux = getJSNameTree()->getValue(i);
+ if (aux) {
+ aux->fetch(xref, &obj);
+ }
if (!obj.isDict()) {
obj.free();
@@ -806,12 +811,12 @@ GBool NameTree::lookup(GooString *name, Object *obj)
}
}
-Object NameTree::getValue(int index)
+Object *NameTree::getValue(int index)
{
if (index < length) {
- return entries[index]->value;
+ return &entries[index]->value;
} else {
- return Object();
+ return nullptr;
}
}
diff --git a/poppler/Catalog.h b/poppler/Catalog.h
index 81b0e125..ed9ec756 100644
--- a/poppler/Catalog.h
+++ b/poppler/Catalog.h
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
-// Copyright (C) 2005, 2007, 2009-2011, 2013 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2005, 2007, 2009-2011, 2013, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
@@ -71,8 +71,8 @@ public:
void init(XRef *xref, Object *tree);
GBool lookup(GooString *name, Object *obj);
int numEntries() { return length; };
- // iterator accessor, note it returns a shallow copy, do not free the object
- Object getValue(int i);
+ // iterator accessor, note it returns a pointer to the internal object, do not free nor delete it
+ Object *getValue(int i);
GooString *getName(int i);
private:
diff --git a/poppler/DCTStream.cc b/poppler/DCTStream.cc
index bfdb0eaf..6bdb0036 100644
--- a/poppler/DCTStream.cc
+++ b/poppler/DCTStream.cc
@@ -5,7 +5,7 @@
// This file is licensed under the GPLv2 or later
//
// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
-// Copyright 2005-2010, 2012 Albert Astals Cid <aacid@kde.org>
+// Copyright 2005-2010, 2012, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2009 Ryszard Trojnacki <rysiek@menel.com>
// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright 2011 Daiki Ueno <ueno@unixuser.org>
@@ -60,16 +60,16 @@ static void str_term_source(j_decompress_ptr cinfo)
{
}
-DCTStream::DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion) :
+DCTStream::DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion) :
FilterStream(strA) {
colorXform = colorXformA;
if (dict != NULL) {
Object obj;
- dict->dictLookup("Width", &obj, recursion);
+ dict->lookup("Width", &obj, recursion);
err.width = (obj.isInt() && obj.getInt() <= JPEG_MAX_DIMENSION) ? obj.getInt() : 0;
obj.free();
- dict->dictLookup("Height", &obj, recursion);
+ dict->lookup("Height", &obj, recursion);
err.height = (obj.isInt() && obj.getInt() <= JPEG_MAX_DIMENSION) ? obj.getInt() : 0;
obj.free();
} else
diff --git a/poppler/DCTStream.h b/poppler/DCTStream.h
index cfa06634..00e0484c 100644
--- a/poppler/DCTStream.h
+++ b/poppler/DCTStream.h
@@ -6,7 +6,7 @@
//
// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
// Copyright 2005 Martin Kretzschmar <martink@gnome.org>
-// Copyright 2005-2007, 2009-2011 Albert Astals Cid <aacid@kde.org>
+// Copyright 2005-2007, 2009-2011, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright 2011 Daiki Ueno <ueno@unixuser.org>
// Copyright 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
@@ -64,7 +64,7 @@ struct str_error_mgr {
class DCTStream: public FilterStream {
public:
- DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion);
+ DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
~DCTStream();
StreamKind getKind() override { return strDCT; }
void reset() override;
diff --git a/poppler/Dict.cc b/poppler/Dict.cc
index c2a94f4a..cdd7d27b 100644
--- a/poppler/Dict.cc
+++ b/poppler/Dict.cc
@@ -16,7 +16,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2008, 2010, 2013, 2014 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2008, 2010, 2013, 2014, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
@@ -108,12 +108,9 @@ Dict *Dict::copy(XRef *xrefA) {
dictA->xref = xrefA;
for (int i=0; i<length; i++) {
if (dictA->entries[i].val.getType() == objDict) {
- Dict *dict = dictA->entries[i].val.getDict();
- Object obj;
- obj.initDict(dict->copy(xrefA));
- dictA->entries[i].val.free();
- dictA->entries[i].val = obj;
- obj.free();
+ Dict *copy = dictA->entries[i].val.getDict()->copy(xrefA);
+ dictA->entries[i].val.initDict(copy);
+ copy->decRef();
}
}
return dictA;
@@ -161,7 +158,8 @@ void Dict::add(char *key, Object *val) {
entries = (DictEntry *)greallocn(entries, size, sizeof(DictEntry));
}
entries[length].key = key;
- entries[length].val = *val;
+ entries[length].val.initNullNoFree();
+ val->shallowCopy(&entries[length].val);
++length;
}
@@ -169,8 +167,8 @@ inline DictEntry *Dict::find(const char *key) {
if (!sorted && length >= SORT_LENGTH_LOWER_LIMIT)
{
dictLocker();
- sorted = gTrue;
- std::sort(entries, entries+length, cmpDictEntries);
+// TODO sorted = gTrue;
+// std::sort(entries, entries+length, cmpDictEntries);
}
if (sorted) {
@@ -208,7 +206,6 @@ void Dict::remove(const char *key) {
} else {
int i;
bool found = false;
- DictEntry tmp;
if(length == 0) {
return;
}
@@ -226,9 +223,11 @@ void Dict::remove(const char *key) {
gfree(entries[i].key);
entries[i].val.free();
length -= 1;
- tmp = entries[length];
- if (i!=length) //don't copy the last entry if it is deleted
- entries[i] = tmp;
+ if (i!=length) {
+ //don't copy the last entry if it is deleted
+ entries[i].key = entries[length].key;
+ entries[length].val.shallowCopy(&entries[i].val);
+ }
}
}
@@ -242,7 +241,7 @@ void Dict::set(const char *key, Object *val) {
if (e) {
dictLocker();
e->val.free();
- e->val = *val;
+ val->shallowCopy(&e->val);
} else {
add (copyString(key), val);
}
diff --git a/poppler/Dict.h b/poppler/Dict.h
index fba99edc..c6b43e40 100644
--- a/poppler/Dict.h
+++ b/poppler/Dict.h
@@ -16,7 +16,7 @@
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
-// Copyright (C) 2010 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2010, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Paweł Wiejacha <pawel.wiejacha@gmail.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
//
@@ -64,9 +64,11 @@ public:
int getLength() { return length; }
// Add an entry. NB: does not copy key.
+ // val becomes a dead object after the call
void add(char *key, Object *val);
// Update the value of an existing entry, otherwise create it
+ // val becomes a dead object after the call
void set(const char *key, Object *val);
// Remove an entry. This invalidate indexes
void remove(const char *key);
diff --git a/poppler/Form.cc b/poppler/Form.cc
index ced3140c..e4a20dd0 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -689,7 +689,6 @@ void FormField::_createWidget (Object *obj, Ref aref)
default:
error(errSyntaxWarning, -1, "SubType on non-terminal field, invalid document?");
numChildren--;
- terminal = false;
}
}
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 37220280..2fa8c7dc 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -817,8 +817,7 @@ void Gfx::go(GBool topLevel) {
// got an argument - save it
} else if (numArgs < maxArgs) {
- args[numArgs++] = obj;
-
+ obj.shallowCopy(&args[numArgs++]);
// too many arguments - something is wrong
} else {
error(errSyntaxError, getPos(), "Too many args in content stream");
@@ -4272,7 +4271,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
GBool maskInvert;
GBool maskInterpolate;
Stream *maskStr;
- Object obj1, obj2;
+ Object obj1;
int i, n;
// get info from the stream
@@ -4378,12 +4377,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
dict->lookup("D", &obj1);
}
if (obj1.isArray()) {
+ Object obj2;
obj1.arrayGet(0, &obj2);
// Table 4.39 says /Decode must be [1 0] or [0 1]. Adobe
// accepts [1.0 0.0] as well.
if (obj2.isNum() && obj2.getNum() >= 0.9)
invert = gTrue;
- obj2.free();
} else if (!obj1.isNull()) {
goto err2;
}
@@ -4418,12 +4417,10 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
dict->lookup("CS", &obj1);
}
if (obj1.isName() && inlineImg) {
+ Object obj2;
res->lookupColorSpace(obj1.getName(), &obj2);
if (!obj2.isNull()) {
- obj1.free();
- obj1 = obj2;
- } else {
- obj2.free();
+ obj2.shallowCopy(&obj1);
}
}
if (!obj1.isNull()) {
@@ -4549,12 +4546,10 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("CS", &obj1);
}
if (obj1.isName()) {
+ Object obj2;
res->lookupColorSpace(obj1.getName(), &obj2);
if (!obj2.isNull()) {
- obj1.free();
- obj1 = obj2;
- } else {
- obj2.free();
+ obj2.shallowCopy(&obj1);
}
}
maskColorSpace = GfxColorSpace::parse(NULL, &obj1, out, state);
@@ -4584,6 +4579,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskWidth, maskHeight, width, height);
} else {
GfxColor matteColor;
+ Object obj2;
for (i = 0; i < colorSpace->getNComps(); i++) {
obj1.getArray()->get(i, &obj2);
if (!obj2.isNum()) {
@@ -4593,7 +4589,6 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
break;
}
matteColor.c[i] = dblToCol(obj2.getNum());
- obj2.free();
}
if (i == colorSpace->getNComps()) {
maskColorMap->setMatteColor(&matteColor);
@@ -4674,13 +4669,13 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("D", &obj1);
}
if (obj1.isArray()) {
+ Object obj2;
obj1.arrayGet(0, &obj2);
// Table 4.39 says /Decode must be [1 0] or [0 1]. Adobe
// accepts [1.0 0.0] as well.
if (obj2.isNum() && obj2.getNum() >= 0.9) {
maskInvert = gTrue;
}
- obj2.free();
} else if (!obj1.isNull()) {
goto err2;
}
@@ -5081,7 +5076,7 @@ Stream *Gfx::buildImageStream() {
// make stream
if (parser->getStream()) {
str = new EmbedStream(parser->getStream(), &dict, gFalse, 0);
- str = str->addFilters(&dict);
+ str = str->addFilters(str->getDict());
} else {
str = NULL;
dict.free();
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index f68b6adc..7775eb50 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -6,7 +6,7 @@
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Pino Toscano <pino@kde.org> (c) 2008
// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
-// Albert Astals Cid <aacid@kde.org> (c) 2010
+// Albert Astals Cid <aacid@kde.org> (c) 2010, 2017
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -265,6 +265,23 @@ Movie::Movie(Object *movieDict, Object *aDict) {
}
}
+Movie::Movie(const Movie &other)
+{
+ ok = other.ok;
+ rotationAngle = other.rotationAngle;
+ width = other.width;
+ height = other.height;
+ showPoster = other.showPoster;
+ MA = other.MA;
+
+ other.poster.copy(&poster);
+
+ if (other.fileName)
+ fileName = other.fileName->copy();
+ else
+ fileName = nullptr;
+}
+
void Movie::getFloatingWindowSize(int *widthA, int *heightA)
{
*widthA = int(width * double(MA.znum) / MA.zdenum);
@@ -272,14 +289,5 @@ void Movie::getFloatingWindowSize(int *widthA, int *heightA)
}
Movie* Movie::copy() {
-
- // call default copy constructor
- Movie* new_movie = new Movie(*this);
-
- if (fileName)
- new_movie->fileName = fileName->copy();
-
- poster.copy(&new_movie->poster);
-
- return new_movie;
+ return new Movie(*this);
}
diff --git a/poppler/Movie.h b/poppler/Movie.h
index 1a162659..587853e8 100644
--- a/poppler/Movie.h
+++ b/poppler/Movie.h
@@ -5,6 +5,7 @@
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
+// Albert Astals Cid <aacid@kde.org> (c) 2017
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -71,6 +72,7 @@ class Movie {
public:
Movie(Object *objMovie, Object *objAct);
Movie(Object *objMovie);
+ Movie(const Movie &movie);
~Movie();
GBool isOk() { return ok; }
diff --git a/poppler/Object.cc b/poppler/Object.cc
index d06bb39f..e84abcc2 100644
--- a/poppler/Object.cc
+++ b/poppler/Object.cc
@@ -13,7 +13,7 @@
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
-// Copyright (C) 2008, 2010, 2012 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2008, 2010, 2012, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
//
// To see a description of the changes please see the Changelog file that
@@ -54,14 +54,36 @@ static const char *objTypeNames[numObjTypes] = {
"error",
"eof",
"none",
- "integer64"
+ "integer64",
+ "dead"
};
#ifdef DEBUG_MEM
int Object::numAlloc[numObjTypes] =
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
+Object::Object(Object&& other)
+{
+ type = other.type;
+ real = other.real; // this is the biggest of the union so it's enough
+ other.type = objDead;
+}
+
+Object& Object::operator=(Object&& other)
+{
+ free();
+ type = other.type;
+ real = other.real; // this is the biggest of the union so it's enough
+ other.type = objDead;
+ return *this;
+}
+
+Object::~Object()
+{
+ free();
+}
+
Object *Object::initArray(XRef *xref) {
initObj(objArray);
array = new Array(xref);
@@ -87,8 +109,11 @@ Object *Object::initStream(Stream *streamA) {
return this;
}
-Object *Object::copy(Object *obj) {
- *obj = *this;
+Object *Object::copy(Object *obj) const {
+ CHECK_NOT_DEAD;
+
+ obj->type = type;
+ obj->real = real; // this is the biggest of the union so it's enough
switch (type) {
case objString:
obj->string = string->copy();
@@ -117,7 +142,20 @@ Object *Object::copy(Object *obj) {
return obj;
}
+Object *Object::shallowCopy(Object *obj)
+{
+ CHECK_NOT_DEAD;
+
+ obj->free();
+ obj->type = type;
+ obj->real = real; // this is the biggest of the union so it's enough
+ type = objDead;
+ return obj;
+}
+
Object *Object::fetch(XRef *xref, Object *obj, int recursion) {
+ CHECK_NOT_DEAD;
+
return (type == objRef && xref) ?
xref->fetch(ref.num, ref.gen, obj, recursion) : copy(obj);
}
@@ -225,6 +263,9 @@ void Object::print(FILE *f) {
case objNone:
fprintf(f, "<none>");
break;
+ case objDead:
+ fprintf(f, "<dead>");
+ break;
case objInt64:
fprintf(f, "%lld", int64g);
break;
diff --git a/poppler/Object.h b/poppler/Object.h
index e3f8f378..8cda79db 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -15,7 +15,7 @@
//
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2008 Kees Cook <kees@outflux.net>
-// Copyright (C) 2008, 2010 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2008, 2010, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 Jakub Wilk <jwilk@jwilk.net>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
@@ -65,6 +65,12 @@
abort(); \
}
+#define CHECK_NOT_DEAD \
+ if (unlikely(type == objDead)) { \
+ error(errInternal, 0, "Call to dead object"); \
+ abort(); \
+ }
+
class XRef;
class Array;
class Dict;
@@ -105,19 +111,20 @@ enum ObjType {
objNone, // uninitialized object
// poppler-only objects
- objInt64 // integer with at least 64-bits
+ objInt64, // integer with at least 64-bits
+ objDead // and object after shallowCopy
};
-#define numObjTypes 15 // total number of object types
+#define numObjTypes 16 // total number of object types
//------------------------------------------------------------------------
// Object
//------------------------------------------------------------------------
#ifdef DEBUG_MEM
-#define initObj(t) zeroUnion(); ++numAlloc[type = t]
+#define initObj(t) free(); zeroUnion(); ++numAlloc[type = t]
#else
-#define initObj(t) zeroUnion(); type = t
+#define initObj(t) free(); zeroUnion(); type = t
#endif
class Object {
@@ -128,6 +135,13 @@ public:
// Default constructor.
Object():
type(objNone) { zeroUnion(); }
+ ~Object();
+
+ Object(Object&& other);
+ Object& operator=(Object&& other);
+
+ Object &operator=(const Object &other) = delete;
+ Object(const Object &other) = delete;
// Initialize an object.
Object *initBool(GBool boolnA)
@@ -142,6 +156,14 @@ public:
{ initObj(objName); name = copyString(nameA); return this; }
Object *initNull()
{ initObj(objNull); return this; }
+ Object *initNullNoFree()
+ {
+ type = objNull;
+#ifdef DEBUG_MEM
+#define initObj(t) ++numAlloc[objNull]
+#endif
+ return this;
+ }
Object *initArray(XRef *xref);
Object *initDict(XRef *xref);
Object *initDict(Dict *dictA);
@@ -157,12 +179,11 @@ public:
Object *initInt64(long long int64gA)
{ initObj(objInt64); int64g = int64gA; return this; }
- // Copy an object.
- Object *copy(Object *obj);
- Object *shallowCopy(Object *obj) {
- *obj = *this;
- return obj;
- }
+ // Copy this to obj
+ Object *copy(Object *obj) const;
+
+ // Copy this to obj. This becomes a none object
+ Object *shallowCopy(Object *obj);
// If object is a Ref, fetch and return the referenced object.
// Otherwise, return a copy of the object.
@@ -172,24 +193,24 @@ public:
void free();
// Type checking.
- ObjType getType() { return type; }
- GBool isBool() { return type == objBool; }
- GBool isInt() { return type == objInt; }
- GBool isReal() { return type == objReal; }
- GBool isNum() { return type == objInt || type == objReal || type == objInt64; }
- GBool isString() { return type == objString; }
- GBool isName() { return type == objName; }
- GBool isNull() { return type == objNull; }
- GBool isArray() { return type == objArray; }
- GBool isDict() { return type == objDict; }
- GBool isStream() { return type == objStream; }
- GBool isRef() { return type == objRef; }
- GBool isCmd() { return type == objCmd; }
- GBool isError() { return type == objError; }
- GBool isEOF() { return type == objEOF; }
- GBool isNone() { return type == objNone; }
- GBool isInt64() { return type == objInt64; }
- GBool isIntOrInt64() { return type == objInt || type == objInt64; }
+ ObjType getType() { CHECK_NOT_DEAD; return type; }
+ GBool isBool() { CHECK_NOT_DEAD; return type == objBool; }
+ GBool isInt() { CHECK_NOT_DEAD; return type == objInt; }
+ GBool isReal() { CHECK_NOT_DEAD; return type == objReal; }
+ GBool isNum() { CHECK_NOT_DEAD; return type == objInt || type == objReal || type == objInt64; }
+ GBool isString() { CHECK_NOT_DEAD; return type == objString; }
+ GBool isName() { CHECK_NOT_DEAD; return type == objName; }
+ GBool isNull() { CHECK_NOT_DEAD; return type == objNull; }
+ GBool isArray() { CHECK_NOT_DEAD; return type == objArray; }
+ GBool isDict() { CHECK_NOT_DEAD; return type == objDict; }
+ GBool isStream() { CHECK_NOT_DEAD; return type == objStream; }
+ GBool isRef() { CHECK_NOT_DEAD; return type == objRef; }
+ GBool isCmd() { CHECK_NOT_DEAD; return type == objCmd; }
+ GBool isError() { CHECK_NOT_DEAD; return type == objError; }
+ GBool isEOF() { CHECK_NOT_DEAD; return type == objEOF; }
+ GBool isNone() { CHECK_NOT_DEAD; return type == objNone; }
+ GBool isInt64() { CHECK_NOT_DEAD; return type == objInt64; }
+ GBool isIntOrInt64() { CHECK_NOT_DEAD; return type == objInt || type == objInt64; }
// Special type checking.
GBool isName(const char *nameA)
diff --git a/poppler/OptionalContent.cc b/poppler/OptionalContent.cc
index 44eef194..dd839707 100644
--- a/poppler/OptionalContent.cc
+++ b/poppler/OptionalContent.cc
@@ -64,7 +64,7 @@ OCGs::OCGs(Object *ocgObject, XRef *xref) :
ocg.free();
ocgList.arrayGetNF(i, &ocg);
if (!ocg.isRef()) {
- ocg.free();
+ delete thisOptionalContentGroup;
break;
}
// TODO: we should create a lookup map from Ref to the OptionalContentGroup
diff --git a/poppler/Page.cc b/poppler/Page.cc
index dca52e4f..cf687c03 100644
--- a/poppler/Page.cc
+++ b/poppler/Page.cc
@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
-// Copyright (C) 2005-2013, 2016 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2005-2013, 2016, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006-2008 Pino Toscano <pino@kde.org>
// Copyright (C) 2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
@@ -393,7 +393,7 @@ void Page::replaceXRef(XRef *xrefA) {
pageDict->lookupNF("AA", &actions);
pageDict->lookup("Resources", &obj1);
if (obj1.isDict()) {
- attrs->replaceResource(obj1);
+ attrs->replaceResource(&obj1);
}
obj1.free();
delete pageDict;
diff --git a/poppler/Page.h b/poppler/Page.h
index 2aaabae9..7a20b55c 100644
--- a/poppler/Page.h
+++ b/poppler/Page.h
@@ -20,7 +20,7 @@
// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2012 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2012, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
//
@@ -107,8 +107,8 @@ public:
? separationInfo.getDict() : (Dict *)NULL; }
Dict *getResourceDict()
{ return resources.isDict() ? resources.getDict() : (Dict *)NULL; }
- void replaceResource(Object obj1)
- { resources.free(); obj1.copy(&resources); }
+ void replaceResource(Object *obj1)
+ { obj1->shallowCopy(&resources); }
// Clip all other boxes to the MediaBox.
void clipBoxes();
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index 28a54607..1be2e9f7 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -13,7 +13,7 @@
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
-// Copyright (C) 2006, 2009, 201, 2010, 2013, 2014 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2006, 2009, 201, 2010, 2013, 2014, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2012 Hib Eris <hib@hiberis.nl>
@@ -274,7 +274,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
}
// get filters
- str = str->addFilters(dict, recursion);
+ str = str->addFilters(str->getDict(), recursion);
return str;
}
diff --git a/poppler/Stream.cc b/poppler/Stream.cc
index 4a9babe4..cb91ca5c 100644
--- a/poppler/Stream.cc
+++ b/poppler/Stream.cc
@@ -14,7 +14,7 @@
// under GPL version 2 or later
//
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
-// Copyright (C) 2006-2010, 2012-2014, 2016 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2006-2010, 2012-2014, 2016, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
@@ -168,22 +168,22 @@ GooString *Stream::getPSFilter(int psLevel, const char *indent) {
return new GooString();
}
-Stream *Stream::addFilters(Object *dict, int recursion) {
+Stream *Stream::addFilters(Dict *dict, int recursion) {
Object obj, obj2;
Object params, params2;
Stream *str;
int i;
str = this;
- dict->dictLookup("Filter", &obj, recursion);
+ dict->lookup("Filter", &obj, recursion);
if (obj.isNull()) {
obj.free();
- dict->dictLookup("F", &obj, recursion);
+ dict->lookup("F", &obj, recursion);
}
- dict->dictLookup("DecodeParms", &params, recursion);
+ dict->lookup("DecodeParms", &params, recursion);
if (params.isNull()) {
params.free();
- dict->dictLookup("DP", &params, recursion);
+ dict->lookup("DP", &params, recursion);
}
if (obj.isName()) {
str = makeFilter(obj.getName(), str, &params, recursion, dict);
@@ -212,7 +212,7 @@ Stream *Stream::addFilters(Object *dict, int recursion) {
return str;
}
-Stream *Stream::makeFilter(char *name, Stream *str, Object *params, int recursion, Object *dict) {
+Stream *Stream::makeFilter(char *name, Stream *str, Object *params, int recursion, Dict *dict) {
int pred; // parameters
int colors;
int bits;
@@ -417,7 +417,7 @@ void FileOutStream::printf(const char *format, ...)
//------------------------------------------------------------------------
BaseStream::BaseStream(Object *dictA, Goffset lengthA) {
- dict = *dictA;
+ dictA->shallowCopy(&dict);
length = lengthA;
}
@@ -788,7 +788,11 @@ FileStream::~FileStream() {
}
BaseStream *FileStream::copy() {
- return new FileStream(file, start, limited, length, &dict);
+ Object dictRef;
+ if (dict.isDict()) {
+ dictRef.initDict(dict.getDict());
+ }
+ return new FileStream(file, start, limited, length, &dictRef);
}
Stream *FileStream::makeSubStream(Goffset startA, GBool limitedA,
@@ -882,8 +886,13 @@ CachedFileStream::~CachedFileStream()
}
BaseStream *CachedFileStream::copy() {
+ Object dictRef;
+ if (dict.isDict()) {
+ dictRef.initDict(dict.getDict());
+ }
+
cc->incRefCnt();
- return new CachedFileStream(cc, start, limited, length, &dict);
+ return new CachedFileStream(cc, start, limited, length, &dictRef);
}
Stream *CachedFileStream::makeSubStream(Goffset startA, GBool limitedA,
@@ -982,7 +991,12 @@ MemStream::~MemStream() {
}
BaseStream *MemStream::copy() {
- return new MemStream(buf, start, length, &dict);
+ Object dictRef;
+ if (dict.isDict()) {
+ dictRef.initDict(dict.getDict());
+ }
+
+ return new MemStream(buf, start, length, &dictRef);
}
Stream *MemStream::makeSubStream(Goffset startA, GBool limited,
diff --git a/poppler/Stream.h b/poppler/Stream.h
index 91b524fe..740f0fc4 100644
--- a/poppler/Stream.h
+++ b/poppler/Stream.h
@@ -15,7 +15,7 @@
//
// Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net>
-// Copyright (C) 2008, 2010, 2011, 2016 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2008, 2010, 2011, 2016, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
@@ -226,13 +226,13 @@ public:
// Add filters to this stream according to the parameters in <dict>.
// Returns the new stream.
- Stream *addFilters(Object *dict, int recursion = 0);
+ Stream *addFilters(Dict *dict, int recursion = 0);
private:
virtual GBool hasGetChars() { return false; }
virtual int getChars(int nChars, Guchar *buffer);
- Stream *makeFilter(char *name, Stream *str, Object *params, int recursion = 0, Object *dict = NULL);
+ Stream *makeFilter(char *name, Stream *str, Object *params, int recursion = 0, Dict *dict = nullptr);
int ref; // reference count
#if MULTITHREADED
@@ -868,7 +868,7 @@ struct DCTHuffTable {
class DCTStream: public FilterStream {
public:
- DCTStream(Stream *strA, int colorXformA, Object *dict, int recursion);
+ DCTStream(Stream *strA, int colorXformA, Dict *dict, int recursion);
virtual ~DCTStream();
virtual StreamKind getKind() { return strDCT; }
virtual void reset();
diff --git a/poppler/StructElement.cc b/poppler/StructElement.cc
index c6688208..0138ad9b 100644
--- a/poppler/StructElement.cc
+++ b/poppler/StructElement.cc
@@ -6,7 +6,7 @@
//
// Copyright 2013, 2014 Igalia S.L.
// Copyright 2014 Luigi Scarso <luigi.scarso@gmail.com>
-// Copyright 2014 Albert Astals Cid <aacid@kde.org>
+// Copyright 2014, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2015 Dmytro Morgun <lztoad@gmail.com>
//
//========================================================================
@@ -1256,9 +1256,7 @@ StructElement *StructElement::parseChild(Object *ref,
mcidObj.free();
if (childObj->dictLookupNF("Pg", &pageRefObj)->isRef()) {
- child->pageRef = pageRefObj;
- } else {
- pageRefObj.free();
+ pageRefObj.shallowCopy(&child->pageRef);
}
} else if (childObj->isDict("OBJR")) {
Object refObj;
@@ -1269,9 +1267,7 @@ StructElement *StructElement::parseChild(Object *ref,
child = new StructElement(refObj.getRef(), treeRoot, this);
if (childObj->dictLookupNF("Pg", &pageRefObj)->isRef()) {
- child->pageRef = pageRefObj;
- } else {
- pageRefObj.free();
+ pageRefObj.shallowCopy(&child->pageRef);
}
} else {
error(errSyntaxError, -1, "Obj object is wrong type ({0:s})", refObj.getTypeName());
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 6ea0fbb6..854f61fb 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -495,7 +495,7 @@ int XRef::resize(int newSize)
for (int i = size; i < newSize; ++i) {
entries[i].offset = -1;
entries[i].type = xrefEntryNone;
- entries[i].obj.initNull ();
+ entries[i].obj.initNullNoFree ();
entries[i].flags = 0;
entries[i].gen = 0;
}
@@ -625,7 +625,6 @@ GBool XRef::readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *fo
goto err1;
}
entry.gen = obj.getInt();
- entry.obj.initNull ();
entry.flags = 0;
obj.free();
parser->getObj(&obj, gTrue);
@@ -638,7 +637,12 @@ GBool XRef::readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *fo
}
obj.free();
if (entries[i].offset == -1) {
- entries[i] = entry;
+ entries[i].offset = entry.offset;
+ entries[i].gen = entry.gen;
+ entries[i].type = entry.type;
+ entries[i].flags = entry.flags;
+ entries[i].obj.initNull();
+
// PDF files of patents from the IBM Intellectual Property
// Network have a bug: the xref table claims to start at 1
// instead of 0.
@@ -646,7 +650,12 @@ GBool XRef::readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *fo
entries[1].offset == 0 && entries[1].gen == 65535 &&
entries[1].type == xrefEntryFree) {
i = first = 0;
- entries[0] = entries[1];
+ entries[0].offset = 0;
+ entries[0].gen = 65535;
+ entries[0].type = xrefEntryFree;
+ entries[0].flags = entries[1].flags;
+ entries[1].obj.shallowCopy(&entries[0].obj);
+
entries[1].offset = -1;
}
}
@@ -1605,7 +1614,7 @@ GBool XRef::parseEntry(Goffset offset, XRefEntry *entry)
Object obj;
obj.initNull();
- Parser parser = Parser(NULL, new Lexer(NULL,
+ Parser parser(NULL, new Lexer(NULL,
str->makeSubStream(offset, gFalse, 20, &obj)), gTrue);
Object obj1, obj2, obj3;
diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc
index dfe48bf8..b1f2be8b 100644
--- a/utils/pdfunite.cc
+++ b/utils/pdfunite.cc
@@ -7,7 +7,7 @@
// Copyright (C) 2011-2015, 2017 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Arseny Solokha <asolokha@gmx.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
-// Copyright (C) 2012, 2014 Albert Astals Cid <aacid@kde.org>
+// Copyright (C) 2012, 2014, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2015 Arthur Stavisky <vovodroid@gmail.com>
@@ -370,7 +370,7 @@ int main (int argc, char *argv[])
pageDict->set("Resources", newResource);
delete newResource;
}
- pages.push_back(page);
+ pages.push_back(std::move(page));
offsets.push_back(numOffset);
docs[i]->markPageObjects(pageDict, yRef, countRef, numOffset, refPage->num, refPage->num);
Object annotsObj;