Commit 0132261ee06e9b94bdc011eb4dc3fcd3a403e5f3

Authored by Jay Berkenbilt
1 parent bac55955

Revert getOwningQPDF, and add getQPDF that returns a reference

ChangeLog
  1 +2022-09-07 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add QPDFObjectHandle::getQPDF(), which returns a reference, as
  4 + an alternative to QPDFObjectHandle::getOwningQPDF().
  5 +
1 2022-09-06 Jay Berkenbilt <ejb@ql.org> 6 2022-09-06 Jay Berkenbilt <ejb@ql.org>
2 7
3 * For all bounding box methods in QPDFPageObjectHelper other than 8 * For all bounding box methods in QPDFPageObjectHelper other than
include/qpdf/QPDFObjectHandle.hh
@@ -661,14 +661,17 @@ class QPDFObjectHandle @@ -661,14 +661,17 @@ class QPDFObjectHandle
661 static QPDFObjectHandle newReserved(QPDF* qpdf); 661 static QPDFObjectHandle newReserved(QPDF* qpdf);
662 662
663 // Provide an owning qpdf and object description. The library does 663 // Provide an owning qpdf and object description. The library does
664 - // this automatically with objects that are read from the  
665 - // input PDF and with objects that are created programmatically  
666 - // and inserted into the QPDF by adding them to an array or a  
667 - // dictionary or creating a new indirect object. Most end user 664 + // this automatically with objects that are read from the input
  665 + // PDF and with objects that are created programmatically and
  666 + // inserted into the QPDF as a new indirect object. Most end user
668 // code will not need to call this. If an object has an owning 667 // code will not need to call this. If an object has an owning
669 // qpdf and object description, it enables qpdf to give warnings 668 // qpdf and object description, it enables qpdf to give warnings
670 // with proper context in some cases where it would otherwise 669 // with proper context in some cases where it would otherwise
671 - // raise exceptions. 670 + // raise exceptions. It is okay to add objects without an
  671 + // owning_qpdf to objects that have one, but it is an error to
  672 + // have a QPDF contain objects with owning_qpdf set to something
  673 + // else. To add objects from another qpdf, use copyForeignObject
  674 + // instead.
672 QPDF_DLL 675 QPDF_DLL
673 void setObjectDescription( 676 void setObjectDescription(
674 QPDF* owning_qpdf, std::string const& object_description); 677 QPDF* owning_qpdf, std::string const& object_description);
@@ -978,23 +981,34 @@ class QPDFObjectHandle @@ -978,23 +981,34 @@ class QPDFObjectHandle
978 int& min_suffix, 981 int& min_suffix,
979 std::set<std::string>* resource_names = nullptr); 982 std::set<std::string>* resource_names = nullptr);
980 983
981 - // If this is an indirect object, return a pointer to the QPDF  
982 - // object that owns an indirect object. Direct objects are not  
983 - // owned by a QPDF. Usage notes:  
984 - //  
985 - // * When allow_nullptr is true, this method will return a null  
986 - // pointer if the object is not owned by a QPDF. Otherwise, an  
987 - // exception is thrown. 984 + // A QPDFObjectHandle has an owning QPDF if it is associated with
  985 + // ("owned by") a specific QPDF object. Indirect objects always
  986 + // have an owning QPDF. Direct objects that are read from the
  987 + // input source will also have an owning QPDF. Programmatically
  988 + // created objects will only have one if setObjectDescription was
  989 + // called.
988 // 990 //
989 - // * You should not retain the value returned by this method for  
990 - // longer than the lifetime of the owning QPDF object. If you  
991 - // retain a QPDFObjectHandle longer than the owning QPDF, when  
992 - // the QPDF object is destroyed, the QPDFObjectHandle will turn  
993 - // into a direct "null" object, and getOwningQPDF() called on it  
994 - // at that time will return a null pointer.  
995 - QPDF_DLL  
996 - QPDF* getOwningQPDF(  
997 - bool allow_nullptr = true, std::string const& error_msg = "") const; 991 + // When the QPDF object that owns an object is destroyed, the
  992 + // object is changed into a null, and its owner is cleared.
  993 + // Therefore you should not retain the value of an owning QPDF
  994 + // beyond the life of the QPDF. If in doubt, ask for it each time
  995 + // you need it.
  996 +
  997 + // getOwningQPDF returns a pointer to the owning QPDF is the
  998 + // object has one. Otherwise, it returns a null pointer. Use this
  999 + // when you are able to handle the case of an object that doesn't
  1000 + // have an owning QPDF.
  1001 + QPDF_DLL
  1002 + QPDF* getOwningQPDF() const;
  1003 + // getQPDF, new in qpdf 11, returns a reference owning QPDF. If
  1004 + // there is none, it throws a runtime_error. Use this when you
  1005 + // know the object has to have an owning QPDF, such as when it's a
  1006 + // known indirect object. Since streams are always indirect
  1007 + // objects, this method can be used safely for streams. If
  1008 + // error_msg is specified, it will be used at the contents of the
  1009 + // runtime_error if there is now owner.
  1010 + QPDF_DLL
  1011 + QPDF& getQPDF(std::string const& error_msg = "") const;
998 1012
999 // Create a shallow copy of an object as a direct object, but do not 1013 // Create a shallow copy of an object as a direct object, but do not
1000 // traverse across indirect object boundaries. That means that, 1014 // traverse across indirect object boundaries. That means that,
libqpdf/QPDF.cc
@@ -2299,14 +2299,14 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) @@ -2299,14 +2299,14 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign)
2299 throw std::logic_error( 2299 throw std::logic_error(
2300 "QPDF::copyForeign called with direct object handle"); 2300 "QPDF::copyForeign called with direct object handle");
2301 } 2301 }
2302 - QPDF* other = foreign.getOwningQPDF(false);  
2303 - if (other == this) { 2302 + QPDF& other = foreign.getQPDF();
  2303 + if (&other == this) {
2304 QTC::TC("qpdf", "QPDF copyForeign not foreign"); 2304 QTC::TC("qpdf", "QPDF copyForeign not foreign");
2305 throw std::logic_error( 2305 throw std::logic_error(
2306 "QPDF::copyForeign called with object from this QPDF"); 2306 "QPDF::copyForeign called with object from this QPDF");
2307 } 2307 }
2308 2308
2309 - ObjCopier& obj_copier = this->m->object_copiers[other->m->unique_id]; 2309 + ObjCopier& obj_copier = this->m->object_copiers[other.m->unique_id];
2310 if (!obj_copier.visiting.empty()) { 2310 if (!obj_copier.visiting.empty()) {
2311 throw std::logic_error("obj_copier.visiting is not empty" 2311 throw std::logic_error("obj_copier.visiting is not empty"
2312 " at the beginning of copyForeignObject"); 2312 " at the beginning of copyForeignObject");
@@ -2490,8 +2490,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) @@ -2490,8 +2490,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
2490 // Copy information from the foreign stream so we can pipe its 2490 // Copy information from the foreign stream so we can pipe its
2491 // data later without keeping the original QPDF object around. 2491 // data later without keeping the original QPDF object around.
2492 2492
2493 - QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(  
2494 - false, "unable to retrieve owning qpdf from foreign stream"); 2493 + QPDF& foreign_stream_qpdf =
  2494 + foreign.getQPDF("unable to retrieve owning qpdf from foreign stream");
2495 2495
2496 auto stream = QPDFObjectHandle::ObjAccessor::asStream(foreign); 2496 auto stream = QPDFObjectHandle::ObjAccessor::asStream(foreign);
2497 if (stream == nullptr) { 2497 if (stream == nullptr) {
@@ -2499,7 +2499,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) @@ -2499,7 +2499,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
2499 " stream object from foreign stream"); 2499 " stream object from foreign stream");
2500 } 2500 }
2501 std::shared_ptr<Buffer> stream_buffer = stream->getStreamDataBuffer(); 2501 std::shared_ptr<Buffer> stream_buffer = stream->getStreamDataBuffer();
2502 - if ((foreign_stream_qpdf->m->immediate_copy_from) && 2502 + if ((foreign_stream_qpdf.m->immediate_copy_from) &&
2503 (stream_buffer == nullptr)) { 2503 (stream_buffer == nullptr)) {
2504 // Pull the stream data into a buffer before attempting 2504 // Pull the stream data into a buffer before attempting
2505 // the copy operation. Do it on the source stream so that 2505 // the copy operation. Do it on the source stream so that
@@ -2529,8 +2529,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) @@ -2529,8 +2529,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
2529 dict.getKey("/DecodeParms")); 2529 dict.getKey("/DecodeParms"));
2530 } else { 2530 } else {
2531 auto foreign_stream_data = std::make_shared<ForeignStreamData>( 2531 auto foreign_stream_data = std::make_shared<ForeignStreamData>(
2532 - foreign_stream_qpdf->m->encp,  
2533 - foreign_stream_qpdf->m->file, 2532 + foreign_stream_qpdf.m->encp,
  2533 + foreign_stream_qpdf.m->file,
2534 foreign.getObjGen(), 2534 foreign.getObjGen(),
2535 stream->getOffset(), 2535 stream->getOffset(),
2536 stream->getLength(), 2536 stream->getLength(),
libqpdf/QPDFFormFieldObjectHelper.cc
@@ -362,12 +362,10 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances) @@ -362,12 +362,10 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances)
362 setFieldAttribute("/V", value); 362 setFieldAttribute("/V", value);
363 } 363 }
364 if (need_appearances) { 364 if (need_appearances) {
365 - QPDF* qpdf = this->oh.getOwningQPDF(  
366 - false, 365 + QPDF& qpdf = this->oh.getQPDF(
367 "QPDFFormFieldObjectHelper::setV called with need_appearances = " 366 "QPDFFormFieldObjectHelper::setV called with need_appearances = "
368 "true on an object that is not associated with an owning QPDF"); 367 "true on an object that is not associated with an owning QPDF");
369 -  
370 - QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true); 368 + QPDFAcroFormDocumentHelper(qpdf).setNeedAppearances(true);
371 } 369 }
372 } 370 }
373 371
@@ -881,7 +879,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance( @@ -881,7 +879,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(
881 if (found_font_in_dr && resources.isDictionary()) { 879 if (found_font_in_dr && resources.isDictionary()) {
882 QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR"); 880 QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR");
883 if (resources.isIndirect()) { 881 if (resources.isIndirect()) {
884 - resources = resources.getOwningQPDF(false)->makeIndirectObject( 882 + resources = resources.getQPDF().makeIndirectObject(
885 resources.shallowCopy()); 883 resources.shallowCopy());
886 AS.getDict().replaceKey("/Resources", resources); 884 AS.getDict().replaceKey("/Resources", resources);
887 } 885 }
libqpdf/QPDFJob.cc
@@ -2194,8 +2194,8 @@ QPDFJob::doUnderOverlayForPage( @@ -2194,8 +2194,8 @@ QPDFJob::doUnderOverlayForPage(
2194 std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>> 2194 std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>>
2195 afdh; 2195 afdh;
2196 auto make_afdh = [&](QPDFPageObjectHelper& ph) { 2196 auto make_afdh = [&](QPDFPageObjectHelper& ph) {
2197 - QPDF* q = ph.getObjectHandle().getOwningQPDF(false);  
2198 - return get_afdh_for_qpdf(afdh, q); 2197 + QPDF& q = ph.getObjectHandle().getQPDF();
  2198 + return get_afdh_for_qpdf(afdh, &q);
2199 }; 2199 };
2200 auto dest_afdh = make_afdh(dest_page); 2200 auto dest_afdh = make_afdh(dest_page);
2201 2201
@@ -2635,7 +2635,7 @@ static QPDFObjectHandle @@ -2635,7 +2635,7 @@ static QPDFObjectHandle
2635 added_page(QPDF& pdf, QPDFObjectHandle page) 2635 added_page(QPDF& pdf, QPDFObjectHandle page)
2636 { 2636 {
2637 QPDFObjectHandle result = page; 2637 QPDFObjectHandle result = page;
2638 - if (page.getOwningQPDF(false) != &pdf) { 2638 + if (&page.getQPDF() != &pdf) {
2639 // Calling copyForeignObject on an object we already copied 2639 // Calling copyForeignObject on an object we already copied
2640 // will give us the already existing copy. 2640 // will give us the already existing copy.
2641 result = pdf.copyForeignObject(page); 2641 result = pdf.copyForeignObject(page);
libqpdf/QPDFObjectHandle.cc
@@ -1668,11 +1668,10 @@ QPDFObjectHandle::coalesceContentStreams() @@ -1668,11 +1668,10 @@ QPDFObjectHandle::coalesceContentStreams()
1668 // incorrect way. However, it can happen in a PDF file whose 1668 // incorrect way. However, it can happen in a PDF file whose
1669 // page structure is direct, which is against spec but still 1669 // page structure is direct, which is against spec but still
1670 // possible to hand construct, as in fuzz issue 27393. 1670 // possible to hand construct, as in fuzz issue 27393.
1671 - QPDF* qpdf = getOwningQPDF(  
1672 - false, 1671 + QPDF& qpdf = getQPDF(
1673 "coalesceContentStreams called on object with no associated PDF file"); 1672 "coalesceContentStreams called on object with no associated PDF file");
1674 1673
1675 - QPDFObjectHandle new_contents = newStream(qpdf); 1674 + QPDFObjectHandle new_contents = newStream(&qpdf);
1676 this->replaceKey("/Contents", new_contents); 1675 this->replaceKey("/Contents", new_contents);
1677 1676
1678 auto provider = std::shared_ptr<StreamDataProvider>( 1677 auto provider = std::shared_ptr<StreamDataProvider>(
@@ -2775,16 +2774,20 @@ QPDFObjectHandle::getObjGen() const @@ -2775,16 +2774,20 @@ QPDFObjectHandle::getObjGen() const
2775 2774
2776 // Indirect object accessors 2775 // Indirect object accessors
2777 QPDF* 2776 QPDF*
2778 -QPDFObjectHandle::getOwningQPDF(  
2779 - bool allow_nullptr, std::string const& error_msg) const 2777 +QPDFObjectHandle::getOwningQPDF() const
  2778 +{
  2779 + return isInitialized() ? this->obj->getQPDF() : nullptr;
  2780 +}
  2781 +
  2782 +QPDF&
  2783 +QPDFObjectHandle::getQPDF(std::string const& error_msg) const
2780 { 2784 {
2781 - // Will be null for direct objects  
2782 auto result = isInitialized() ? this->obj->getQPDF() : nullptr; 2785 auto result = isInitialized() ? this->obj->getQPDF() : nullptr;
2783 - if (!allow_nullptr && (result == nullptr)) { 2786 + if (result == nullptr) {
2784 throw std::runtime_error( 2787 throw std::runtime_error(
2785 error_msg == "" ? "attempt to use a null qpdf object" : error_msg); 2788 error_msg == "" ? "attempt to use a null qpdf object" : error_msg);
2786 } 2789 }
2787 - return result; 2790 + return *result;
2788 } 2791 }
2789 2792
2790 void 2793 void
libqpdf/QPDFPageObjectHelper.cc
@@ -477,8 +477,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow) @@ -477,8 +477,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
477 this->oh.replaceKey( 477 this->oh.replaceKey(
478 "/Contents", 478 "/Contents",
479 QPDFObjectHandle::newStream( 479 QPDFObjectHandle::newStream(
480 - this->oh.getOwningQPDF(false),  
481 - b.getBufferSharedPointer())); 480 + &this->oh.getQPDF(), b.getBufferSharedPointer()));
482 } 481 }
483 } 482 }
484 } else { 483 } else {
@@ -729,12 +728,10 @@ QPDFPageObjectHelper::removeUnreferencedResources() @@ -729,12 +728,10 @@ QPDFPageObjectHelper::removeUnreferencedResources()
729 QPDFPageObjectHelper 728 QPDFPageObjectHelper
730 QPDFPageObjectHelper::shallowCopyPage() 729 QPDFPageObjectHelper::shallowCopyPage()
731 { 730 {
732 - QPDF* qpdf = this->oh.getOwningQPDF(  
733 - false, 731 + QPDF& qpdf = this->oh.getQPDF(
734 "QPDFPageObjectHelper::shallowCopyPage called with a direct object"); 732 "QPDFPageObjectHelper::shallowCopyPage called with a direct object");
735 -  
736 QPDFObjectHandle new_page = this->oh.shallowCopy(); 733 QPDFObjectHandle new_page = this->oh.shallowCopy();
737 - return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page)); 734 + return QPDFPageObjectHelper(qpdf.makeIndirectObject(new_page));
738 } 735 }
739 736
740 QPDFObjectHandle::Matrix 737 QPDFObjectHandle::Matrix
@@ -788,11 +785,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert) @@ -788,11 +785,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert)
788 QPDFObjectHandle 785 QPDFObjectHandle
789 QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations) 786 QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
790 { 787 {
791 - QPDF* qpdf = this->oh.getOwningQPDF(  
792 - false, 788 + QPDF& qpdf = this->oh.getQPDF(
793 "QPDFPageObjectHelper::getFormXObjectForPage called with a direct " 789 "QPDFPageObjectHelper::getFormXObjectForPage called with a direct "
794 "object"); 790 "object");
795 - QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf); 791 + QPDFObjectHandle result = QPDFObjectHandle::newStream(&qpdf);
796 QPDFObjectHandle newdict = result.getDict(); 792 QPDFObjectHandle newdict = result.getDict();
797 newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); 793 newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
798 newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); 794 newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
@@ -961,10 +957,8 @@ QPDFPageObjectHelper::placeFormXObject( @@ -961,10 +957,8 @@ QPDFPageObjectHelper::placeFormXObject(
961 void 957 void
962 QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) 958 QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
963 { 959 {
964 - QPDF* qpdf = this->oh.getOwningQPDF(  
965 - false, 960 + QPDF& qpdf = this->oh.getQPDF(
966 "QPDFPageObjectHelper::flattenRotation called with a direct object"); 961 "QPDFPageObjectHelper::flattenRotation called with a direct object");
967 -  
968 auto rotate_oh = this->oh.getKey("/Rotate"); 962 auto rotate_oh = this->oh.getKey("/Rotate");
969 int rotate = 0; 963 int rotate = 0;
970 if (rotate_oh.isInteger()) { 964 if (rotate_oh.isInteger()) {
@@ -1067,8 +1061,9 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) @@ -1067,8 +1061,9 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
1067 break; 1061 break;
1068 } 1062 }
1069 std::string cm_str = std::string("q\n") + cm.unparse() + " cm\n"; 1063 std::string cm_str = std::string("q\n") + cm.unparse() + " cm\n";
1070 - this->oh.addPageContents(QPDFObjectHandle::newStream(qpdf, cm_str), true);  
1071 - this->oh.addPageContents(QPDFObjectHandle::newStream(qpdf, "\nQ\n"), false); 1064 + this->oh.addPageContents(QPDFObjectHandle::newStream(&qpdf, cm_str), true);
  1065 + this->oh.addPageContents(
  1066 + QPDFObjectHandle::newStream(&qpdf, "\nQ\n"), false);
1072 this->oh.removeKey("/Rotate"); 1067 this->oh.removeKey("/Rotate");
1073 QPDFObjectHandle rotate_obj = getAttribute("/Rotate", false); 1068 QPDFObjectHandle rotate_obj = getAttribute("/Rotate", false);
1074 if (!rotate_obj.isNull()) { 1069 if (!rotate_obj.isNull()) {
@@ -1083,7 +1078,7 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) @@ -1083,7 +1078,7 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
1083 std::set<QPDFObjGen> old_fields; 1078 std::set<QPDFObjGen> old_fields;
1084 std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; 1079 std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph;
1085 if (!afdh) { 1080 if (!afdh) {
1086 - afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*qpdf); 1081 + afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(qpdf);
1087 afdh = afdhph.get(); 1082 afdh = afdhph.get();
1088 } 1083 }
1089 afdh->transformAnnotations( 1084 afdh->transformAnnotations(
@@ -1108,11 +1103,9 @@ QPDFPageObjectHelper::copyAnnotations( @@ -1108,11 +1103,9 @@ QPDFPageObjectHelper::copyAnnotations(
1108 return; 1103 return;
1109 } 1104 }
1110 1105
1111 - QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF(  
1112 - false, 1106 + QPDF& from_qpdf = from_page.getObjectHandle().getQPDF(
1113 "QPDFPageObjectHelper::copyAnnotations: from page is a direct object"); 1107 "QPDFPageObjectHelper::copyAnnotations: from page is a direct object");
1114 - QPDF* this_qpdf = this->oh.getOwningQPDF(  
1115 - false, 1108 + QPDF& this_qpdf = this->oh.getQPDF(
1116 "QPDFPageObjectHelper::copyAnnotations: this page is a direct object"); 1109 "QPDFPageObjectHelper::copyAnnotations: this page is a direct object");
1117 1110
1118 std::vector<QPDFObjectHandle> new_annots; 1111 std::vector<QPDFObjectHandle> new_annots;
@@ -1121,19 +1114,19 @@ QPDFPageObjectHelper::copyAnnotations( @@ -1121,19 +1114,19 @@ QPDFPageObjectHelper::copyAnnotations(
1121 std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; 1114 std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph;
1122 std::shared_ptr<QPDFAcroFormDocumentHelper> from_afdhph; 1115 std::shared_ptr<QPDFAcroFormDocumentHelper> from_afdhph;
1123 if (!afdh) { 1116 if (!afdh) {
1124 - afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*this_qpdf); 1117 + afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(this_qpdf);
1125 afdh = afdhph.get(); 1118 afdh = afdhph.get();
1126 } 1119 }
1127 - if (this_qpdf == from_qpdf) { 1120 + if (&this_qpdf == &from_qpdf) {
1128 from_afdh = afdh; 1121 from_afdh = afdh;
1129 } else if (from_afdh) { 1122 } else if (from_afdh) {
1130 - if (from_afdh->getQPDF().getUniqueId() != from_qpdf->getUniqueId()) { 1123 + if (from_afdh->getQPDF().getUniqueId() != from_qpdf.getUniqueId()) {
1131 throw std::logic_error( 1124 throw std::logic_error(
1132 "QPDFAcroFormDocumentHelper::copyAnnotations: from_afdh" 1125 "QPDFAcroFormDocumentHelper::copyAnnotations: from_afdh"
1133 " is not from the same QPDF as from_page"); 1126 " is not from the same QPDF as from_page");
1134 } 1127 }
1135 } else { 1128 } else {
1136 - from_afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*from_qpdf); 1129 + from_afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(from_qpdf);
1137 from_afdh = from_afdhph.get(); 1130 from_afdh = from_afdhph.get();
1138 } 1131 }
1139 1132
@@ -1143,7 +1136,7 @@ QPDFPageObjectHelper::copyAnnotations( @@ -1143,7 +1136,7 @@ QPDFPageObjectHelper::copyAnnotations(
1143 new_fields, 1136 new_fields,
1144 old_fields, 1137 old_fields,
1145 cm, 1138 cm,
1146 - from_qpdf, 1139 + &from_qpdf,
1147 from_afdh); 1140 from_afdh);
1148 afdh->addAndRenameFormFields(new_fields); 1141 afdh->addAndRenameFormFields(new_fields);
1149 auto annots = this->oh.getKey("/Annots"); 1142 auto annots = this->oh.getKey("/Annots");
libqpdf/QPDF_pages.cc
@@ -233,7 +233,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos) @@ -233,7 +233,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
233 newpage = makeIndirectObject(newpage); 233 newpage = makeIndirectObject(newpage);
234 } else if (newpage.getOwningQPDF() != this) { 234 } else if (newpage.getOwningQPDF() != this) {
235 QTC::TC("qpdf", "QPDF insert foreign page"); 235 QTC::TC("qpdf", "QPDF insert foreign page");
236 - newpage.getOwningQPDF(false)->pushInheritedAttributesToPage(); 236 + newpage.getQPDF().pushInheritedAttributesToPage();
237 newpage = copyForeignObject(newpage); 237 newpage = copyForeignObject(newpage);
238 } else { 238 } else {
239 QTC::TC("qpdf", "QPDF insert indirect page"); 239 QTC::TC("qpdf", "QPDF insert indirect page");
manual/release-notes.rst
@@ -208,6 +208,11 @@ For a detailed list of changes, please see the file @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file
208 generally not happen for correct code, but at least the 208 generally not happen for correct code, but at least the
209 situation is detectible now. 209 situation is detectible now.
210 210
  211 + - The method ``QPDFObjectHandle::getQPDF`` returns a ``QPDF&``
  212 + (rather than a ``QPDF*``) and is an alternative to
  213 + ``QPDFObjectHandle::getOwningQPDF`` for when the object is known
  214 + to have an owning ``QPDF``.
  215 +
211 - It is now possible to test ``QPDFObjectHandle`` equality with 216 - It is now possible to test ``QPDFObjectHandle`` equality with
212 ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if 217 ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if
213 they point to the same underlying object, meaning changes to one 218 they point to the same underlying object, meaning changes to one