Commit 6755a86734176caa1a3c38ad6db5bc3a01be8505
1 parent
21753001
comment on memory leak fix
git-svn-id: svn+q:///qpdf/trunk@979 71b93d88-0707-0410-a8cf-f5a4172ac649
Showing
2 changed files
with
18 additions
and
0 deletions
libqpdf/QPDF.cc
| @@ -277,6 +277,20 @@ QPDF::QPDF() : | @@ -277,6 +277,20 @@ QPDF::QPDF() : | ||
| 277 | 277 | ||
| 278 | QPDF::~QPDF() | 278 | QPDF::~QPDF() |
| 279 | { | 279 | { |
| 280 | + // If two objects are mutually referential (through each object | ||
| 281 | + // having an array or dictionary that contains an indirect | ||
| 282 | + // reference to the other), the circular references in the | ||
| 283 | + // PointerHolder objects will prevent the objects from being | ||
| 284 | + // deleted. Walk through all objects in the object cache, which | ||
| 285 | + // is those objects that we read from the file, and break all | ||
| 286 | + // resolved references. At this point, obviously no one is still | ||
| 287 | + // using the QPDF object, but we'll explicitly clear the xref | ||
| 288 | + // table anyway just to prevent any possibility of resolve() | ||
| 289 | + // succeeding. Note that we can't break references like this at | ||
| 290 | + // any time when the QPDF object is active. If we do, the next | ||
| 291 | + // reference will reread the object from the file, which would | ||
| 292 | + // have the effect of undoing any modifications that may have been | ||
| 293 | + // made to any of the objects. | ||
| 280 | this->xref_table.clear(); | 294 | this->xref_table.clear(); |
| 281 | for (std::map<ObjGen, ObjCache>::iterator iter = this->obj_cache.begin(); | 295 | for (std::map<ObjGen, ObjCache>::iterator iter = this->obj_cache.begin(); |
| 282 | iter != obj_cache.end(); ++iter) | 296 | iter != obj_cache.end(); ++iter) |
libqpdf/QPDFObjectHandle.cc
| @@ -44,6 +44,10 @@ QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) : | @@ -44,6 +44,10 @@ QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) : | ||
| 44 | void | 44 | void |
| 45 | QPDFObjectHandle::releaseResolved() | 45 | QPDFObjectHandle::releaseResolved() |
| 46 | { | 46 | { |
| 47 | + // Recursively break any resolved references to indirect objects. | ||
| 48 | + // Do not cross over indirect object boundaries to avoid an | ||
| 49 | + // infinite loop. This method may only be called during final | ||
| 50 | + // destruction. See comments in QPDF::~QPDF(). | ||
| 47 | if (isIndirect()) | 51 | if (isIndirect()) |
| 48 | { | 52 | { |
| 49 | if (this->obj.getPointer()) | 53 | if (this->obj.getPointer()) |