aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2022-08-06 20:52:07 +0200
committerm-holger <m-holger@kubitscheck.org>2022-08-28 23:15:59 +0200
commitc53d54b13dc6ad369646a09c64d392549effac38 (patch)
treec26a8d6477b5a175f483affed2782a969d39142d
parentcef6425bcac678157f58e9eafabb7e63c5831d18 (diff)
downloadqpdf-c53d54b13dc6ad369646a09c64d392549effac38.tar.zst
Add optional parameter allow_nullptr to QPDFObjectHandle::getOwningQPDF
Also, inline method and add optional parameter error_msg.
-rw-r--r--include/qpdf/QPDFObjectHandle.hh19
-rw-r--r--libqpdf/QPDF.cc10
-rw-r--r--libqpdf/QPDFFormFieldObjectHelper.cc14
-rw-r--r--libqpdf/QPDFJob.cc4
-rw-r--r--libqpdf/QPDFObjectHandle.cc27
-rw-r--r--libqpdf/QPDFPageObjectHelper.cc45
-rw-r--r--libqpdf/QPDF_pages.cc2
-rw-r--r--libqpdf/QTC.cc2
8 files changed, 59 insertions, 64 deletions
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 5d9f52d5..4b054928 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -957,9 +957,11 @@ class QPDFObjectHandle
std::set<std::string>* resource_names = nullptr);
// Return the QPDF object that owns an indirect object. Returns
- // null for a direct object.
+ // null for a direct object if allow_nullptr is set to true or
+ // throws a runtime error otherwise.
QPDF_DLL
- QPDF* getOwningQPDF();
+ inline QPDF*
+ getOwningQPDF(bool allow_nullptr = true, std::string const& error_msg = "");
// Create a shallow copy of an object as a direct object, but do not
// traverse across indirect object boundaries. That means that,
@@ -1876,4 +1878,17 @@ QPDFObjectHandle::isInitialized() const
return initialized;
}
+// Indirect object accessors
+inline QPDF*
+QPDFObjectHandle::getOwningQPDF(
+ bool allow_nullptr, std::string const& error_msg)
+{
+ // Will be null for direct objects
+ if (!allow_nullptr && (this->qpdf == nullptr)) {
+ throw std::runtime_error(
+ error_msg == "" ? "attempt to use a null qpdf object" : error_msg);
+ }
+ return this->qpdf;
+}
+
#endif // QPDFOBJECTHANDLE_HH
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index b96b0674..6ae74b25 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -2266,7 +2266,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign)
throw std::logic_error(
"QPDF::copyForeign called with direct object handle");
}
- QPDF* other = foreign.getOwningQPDF();
+ QPDF* other = foreign.getOwningQPDF(false);
if (other == this) {
QTC::TC("qpdf", "QPDF copyForeign not foreign");
throw std::logic_error(
@@ -2456,11 +2456,9 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
QPDFObjGen local_og(result.getObjGen());
// Copy information from the foreign stream so we can pipe its
// data later without keeping the original QPDF object around.
- QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
- if (!foreign_stream_qpdf) {
- throw std::logic_error("unable to retrieve owning qpdf"
- " from foreign stream");
- }
+ QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(
+ false, "unable to retrieve owning qpdf from foreign stream");
+
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(
QPDFObjectHandle::ObjAccessor::getObject(foreign).get());
if (!stream) {
diff --git a/libqpdf/QPDFFormFieldObjectHelper.cc b/libqpdf/QPDFFormFieldObjectHelper.cc
index 5ff41edd..e56024af 100644
--- a/libqpdf/QPDFFormFieldObjectHelper.cc
+++ b/libqpdf/QPDFFormFieldObjectHelper.cc
@@ -362,13 +362,11 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances)
setFieldAttribute("/V", value);
}
if (need_appearances) {
- QPDF* qpdf = this->oh.getOwningQPDF();
- if (!qpdf) {
- throw std::logic_error(
- "QPDFFormFieldObjectHelper::setV called with"
- " need_appearances = true on an object that is"
- " not associated with an owning QPDF");
- }
+ QPDF* qpdf = this->oh.getOwningQPDF(
+ false,
+ "QPDFFormFieldObjectHelper::setV called with need_appearances = "
+ "true on an object that is not associated with an owning QPDF");
+
QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true);
}
}
@@ -883,7 +881,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(
if (found_font_in_dr && resources.isDictionary()) {
QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR");
if (resources.isIndirect()) {
- resources = resources.getOwningQPDF()->makeIndirectObject(
+ resources = resources.getOwningQPDF(false)->makeIndirectObject(
resources.shallowCopy());
AS.getDict().replaceKey("/Resources", resources);
}
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index f8d963b2..15a81854 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -2161,7 +2161,7 @@ QPDFJob::doUnderOverlayForPage(
std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>>
afdh;
auto make_afdh = [&](QPDFPageObjectHelper& ph) {
- QPDF* q = ph.getObjectHandle().getOwningQPDF();
+ QPDF* q = ph.getObjectHandle().getOwningQPDF(false);
return get_afdh_for_qpdf(afdh, q);
};
auto dest_afdh = make_afdh(dest_page);
@@ -2597,7 +2597,7 @@ static QPDFObjectHandle
added_page(QPDF& pdf, QPDFObjectHandle page)
{
QPDFObjectHandle result = page;
- if (page.getOwningQPDF() != &pdf) {
+ if (page.getOwningQPDF(false) != &pdf) {
// Calling copyForeignObject on an object we already copied
// will give us the already existing copy.
result = pdf.copyForeignObject(page);
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index cf5460d7..8a2d59e3 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -1207,14 +1207,6 @@ QPDFObjectHandle::getUniqueResourceName(
" QPDFObjectHandle::getUniqueResourceName");
}
-// Indirect object accessors
-QPDF*
-QPDFObjectHandle::getOwningQPDF()
-{
- // Will be null for direct objects
- return this->qpdf;
-}
-
// Dictionary mutators
void
@@ -1634,16 +1626,15 @@ QPDFObjectHandle::coalesceContentStreams()
// files may have pages that are invalid in other ways.
return;
}
- QPDF* qpdf = getOwningQPDF();
- if (qpdf == nullptr) {
- // Should not be possible for a page object to not have an
- // owning PDF unless it was manually constructed in some
- // incorrect way. However, it can happen in a PDF file whose
- // page structure is direct, which is against spec but still
- // possible to hand construct, as in fuzz issue 27393.
- throw std::runtime_error("coalesceContentStreams called on object"
- " with no associated PDF file");
- }
+ // Should not be possible for a page object to not have an
+ // owning PDF unless it was manually constructed in some
+ // incorrect way. However, it can happen in a PDF file whose
+ // page structure is direct, which is against spec but still
+ // possible to hand construct, as in fuzz issue 27393.
+ QPDF* qpdf = getOwningQPDF(
+ false,
+ "coalesceContentStreams called on object with no associated PDF file");
+
QPDFObjectHandle new_contents = newStream(qpdf);
this->replaceKey("/Contents", new_contents);
diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc
index 9ad75cf8..23a54231 100644
--- a/libqpdf/QPDFPageObjectHelper.cc
+++ b/libqpdf/QPDFPageObjectHelper.cc
@@ -432,7 +432,8 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
this->oh.replaceKey(
"/Contents",
QPDFObjectHandle::newStream(
- this->oh.getOwningQPDF(), b.getBufferSharedPointer()));
+ this->oh.getOwningQPDF(false),
+ b.getBufferSharedPointer()));
}
}
} else {
@@ -683,11 +684,10 @@ QPDFPageObjectHelper::removeUnreferencedResources()
QPDFPageObjectHelper
QPDFPageObjectHelper::shallowCopyPage()
{
- QPDF* qpdf = this->oh.getOwningQPDF();
- if (!qpdf) {
- throw std::runtime_error("QPDFPageObjectHelper::shallowCopyPage"
- " called with a direct object");
- }
+ QPDF* qpdf = this->oh.getOwningQPDF(
+ false,
+ "QPDFPageObjectHelper::shallowCopyPage called with a direct object");
+
QPDFObjectHandle new_page = this->oh.shallowCopy();
return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
}
@@ -743,11 +743,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert)
QPDFObjectHandle
QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
{
- QPDF* qpdf = this->oh.getOwningQPDF();
- if (!qpdf) {
- throw std::runtime_error("QPDFPageObjectHelper::getFormXObjectForPage"
- " called with a direct object");
- }
+ QPDF* qpdf = this->oh.getOwningQPDF(
+ false,
+ "QPDFPageObjectHelper::getFormXObjectForPage called with a direct "
+ "object");
QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf);
QPDFObjectHandle newdict = result.getDict();
newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
@@ -917,11 +916,9 @@ QPDFPageObjectHelper::placeFormXObject(
void
QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
{
- QPDF* qpdf = this->oh.getOwningQPDF();
- if (!qpdf) {
- throw std::runtime_error("QPDFPageObjectHelper::flattenRotation"
- " called with a direct object");
- }
+ QPDF* qpdf = this->oh.getOwningQPDF(
+ false,
+ "QPDFPageObjectHelper::flattenRotation called with a direct object");
auto rotate_oh = this->oh.getKey("/Rotate");
int rotate = 0;
@@ -1066,16 +1063,12 @@ QPDFPageObjectHelper::copyAnnotations(
return;
}
- QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF();
- if (!from_qpdf) {
- throw std::runtime_error("QPDFPageObjectHelper::copyAnnotations:"
- " from page is a direct object");
- }
- QPDF* this_qpdf = this->oh.getOwningQPDF();
- if (!this_qpdf) {
- throw std::runtime_error("QPDFPageObjectHelper::copyAnnotations:"
- " this page is a direct object");
- }
+ QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF(
+ false,
+ "QPDFPageObjectHelper::copyAnnotations: from page is a direct object");
+ QPDF* this_qpdf = this->oh.getOwningQPDF(
+ false,
+ "QPDFPageObjectHelper::copyAnnotations: this page is a direct object");
std::vector<QPDFObjectHandle> new_annots;
std::vector<QPDFObjectHandle> new_fields;
diff --git a/libqpdf/QPDF_pages.cc b/libqpdf/QPDF_pages.cc
index e1a3b2c1..8c9bfbaa 100644
--- a/libqpdf/QPDF_pages.cc
+++ b/libqpdf/QPDF_pages.cc
@@ -234,7 +234,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
newpage = makeIndirectObject(newpage);
} else if (newpage.getOwningQPDF() != this) {
QTC::TC("qpdf", "QPDF insert foreign page");
- newpage.getOwningQPDF()->pushInheritedAttributesToPage();
+ newpage.getOwningQPDF(false)->pushInheritedAttributesToPage();
newpage = copyForeignObject(newpage);
} else {
QTC::TC("qpdf", "QPDF insert indirect page");
diff --git a/libqpdf/QTC.cc b/libqpdf/QTC.cc
index 1ca79c05..8188846c 100644
--- a/libqpdf/QTC.cc
+++ b/libqpdf/QTC.cc
@@ -1,8 +1,8 @@
#include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh>
-#include <set>
#include <map>
+#include <set>
#include <stdio.h>
static bool