Commit 5911a348a5ae9065610be5fe5f251cab399a52b8

Authored by Jay Berkenbilt
1 parent 18a583e8

Fix TODO notes on multiple direct object parent issue

Showing 1 changed file with 34 additions and 21 deletions
... ... @@ -787,27 +787,40 @@ Rejected Ideas
787 787  
788 788 * Fix Multiple Direct Object Parent Issue
789 789  
790   - These are some ideas I had before m-holger's changes to split
791   - QPDFValue from QPDFObject. These notes were written prior to the
792   - split of QPDFObject into QPDFObject and QPDFValue and don't work
793   - directly with the new implementation. I think they are still basic
794   - valid after adjusting to the new structure, but I think they would
795   - come at too high a performance cost to be worth doing.
  790 + This idea was rejected because it would be complicated to implement
  791 + and would likely have a high performance cost to fix what is not
  792 + really that big of a problem in practice.
  793 +
  794 + It is possible for a QPDFObjectHandle for a direct object to be
  795 + contained inside of multiple QPDFObjectHandle objects or even
  796 + replicated across multiple QPDF objects. This creates a potentially
  797 + confusing and unintentional aliasing of direct objects. There are
  798 + known cases in the qpdf library where this happens including page
  799 + splitting and merging (particularly with page labels, and possibly
  800 + with other cases), and also with unsafeShallowCopy. Disallowing this
  801 + would incur a significant performance penalty and is probably not
  802 + worth doing. If we were to do it, here are some ideas.
796 803  
797 804 * Add std::weak_ptr<QPDFObject> parent to QPDFObject. When adding a
798 805 direct object to an array or dictionary, set its parent. When
799   - removing it, clear the parent pointer.
800   - * When a direct object that already has a parent is added to
801   - something, it is a warning and will become an error in qpdf 12.
802   - There needs to be unsafe add methods used by unsafeShallowCopy.
803   - These will add but not modify the parent pointer.
804   -
805   - This allows an object to be moved from one object to another by
806   - removing it, which returns the now orphaned object, and then inserting
807   - it somewhere else. It also doesn't break the pattern of adding a
808   - direct object to something and subsequently mutating it. It just
809   - prevents the same object from being added to more than one thing.
810   -
811   - Note that arrays and dictionaries still need to contain
812   - QPDFObjectHandle because of indirect objects. This only pertains to
813   - direct objects, which are always "resolved" in QPDFObjectHandle.
  806 + removing it, clear the parent pointer. The parent pointer would
  807 + always be null for indirect objects, so the parent pointer, which
  808 + would reside in QPDFObject, would have to be managed by
  809 + QPDFObjectHandle. This is because QPDFObject can't tell the
  810 + difference between a resolved indirect object and a direct object.
  811 +
  812 + * Phase 1: When a direct object that already has a parent is added
  813 + to a dictionary or array, issue a warning. There would need to be
  814 + unsafe add methods used by unsafeShallowCopy. These would add but
  815 + not modify the parent pointer.
  816 +
  817 + * Phase 2: In the next major release, make the multiple parent case
  818 + an error. Require people to create a copy. The unsafe operations
  819 + would still have to be permitted.
  820 +
  821 + This approach would allow an object to be moved from one object to
  822 + another by removing it, which returns the now orphaned object, and
  823 + then inserting it somewhere else. It also doesn't break the pattern
  824 + of adding a direct object to something and subsequently mutating it.
  825 + It just prevents the same object from being added to more than one
  826 + thing.
... ...