mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 07:12:28 +00:00
Merge pull request #747 from m-holger/new_stream
Add optional parameter allow_nullptr to QPDFObjectHandle::getOwningQPDF
This commit is contained in:
commit
0adfd74f8b
@ -957,9 +957,11 @@ class QPDFObjectHandle
|
|||||||
std::set<std::string>* resource_names = nullptr);
|
std::set<std::string>* resource_names = nullptr);
|
||||||
|
|
||||||
// Return the QPDF object that owns an indirect object. Returns
|
// 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_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
|
// Create a shallow copy of an object as a direct object, but do not
|
||||||
// traverse across indirect object boundaries. That means that,
|
// traverse across indirect object boundaries. That means that,
|
||||||
@ -1876,4 +1878,17 @@ QPDFObjectHandle::isInitialized() const
|
|||||||
return initialized;
|
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
|
#endif // QPDFOBJECTHANDLE_HH
|
||||||
|
@ -2266,7 +2266,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign)
|
|||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
"QPDF::copyForeign called with direct object handle");
|
"QPDF::copyForeign called with direct object handle");
|
||||||
}
|
}
|
||||||
QPDF* other = foreign.getOwningQPDF();
|
QPDF* other = foreign.getOwningQPDF(false);
|
||||||
if (other == this) {
|
if (other == this) {
|
||||||
QTC::TC("qpdf", "QPDF copyForeign not foreign");
|
QTC::TC("qpdf", "QPDF copyForeign not foreign");
|
||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
@ -2456,11 +2456,9 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
|
|||||||
QPDFObjGen local_og(result.getObjGen());
|
QPDFObjGen local_og(result.getObjGen());
|
||||||
// Copy information from the foreign stream so we can pipe its
|
// Copy information from the foreign stream so we can pipe its
|
||||||
// data later without keeping the original QPDF object around.
|
// data later without keeping the original QPDF object around.
|
||||||
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
|
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(
|
||||||
if (!foreign_stream_qpdf) {
|
false, "unable to retrieve owning qpdf from foreign stream");
|
||||||
throw std::logic_error("unable to retrieve owning qpdf"
|
|
||||||
" from foreign stream");
|
|
||||||
}
|
|
||||||
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(
|
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(
|
||||||
QPDFObjectHandle::ObjAccessor::getObject(foreign).get());
|
QPDFObjectHandle::ObjAccessor::getObject(foreign).get());
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
|
@ -362,13 +362,11 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances)
|
|||||||
setFieldAttribute("/V", value);
|
setFieldAttribute("/V", value);
|
||||||
}
|
}
|
||||||
if (need_appearances) {
|
if (need_appearances) {
|
||||||
QPDF* qpdf = this->oh.getOwningQPDF();
|
QPDF* qpdf = this->oh.getOwningQPDF(
|
||||||
if (!qpdf) {
|
false,
|
||||||
throw std::logic_error(
|
"QPDFFormFieldObjectHelper::setV called with need_appearances = "
|
||||||
"QPDFFormFieldObjectHelper::setV called with"
|
"true on an object that is not associated with an owning QPDF");
|
||||||
" need_appearances = true on an object that is"
|
|
||||||
" not associated with an owning QPDF");
|
|
||||||
}
|
|
||||||
QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true);
|
QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,7 +881,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(
|
|||||||
if (found_font_in_dr && resources.isDictionary()) {
|
if (found_font_in_dr && resources.isDictionary()) {
|
||||||
QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR");
|
QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR");
|
||||||
if (resources.isIndirect()) {
|
if (resources.isIndirect()) {
|
||||||
resources = resources.getOwningQPDF()->makeIndirectObject(
|
resources = resources.getOwningQPDF(false)->makeIndirectObject(
|
||||||
resources.shallowCopy());
|
resources.shallowCopy());
|
||||||
AS.getDict().replaceKey("/Resources", resources);
|
AS.getDict().replaceKey("/Resources", resources);
|
||||||
}
|
}
|
||||||
|
@ -2161,7 +2161,7 @@ QPDFJob::doUnderOverlayForPage(
|
|||||||
std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>>
|
std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>>
|
||||||
afdh;
|
afdh;
|
||||||
auto make_afdh = [&](QPDFPageObjectHelper& ph) {
|
auto make_afdh = [&](QPDFPageObjectHelper& ph) {
|
||||||
QPDF* q = ph.getObjectHandle().getOwningQPDF();
|
QPDF* q = ph.getObjectHandle().getOwningQPDF(false);
|
||||||
return get_afdh_for_qpdf(afdh, q);
|
return get_afdh_for_qpdf(afdh, q);
|
||||||
};
|
};
|
||||||
auto dest_afdh = make_afdh(dest_page);
|
auto dest_afdh = make_afdh(dest_page);
|
||||||
@ -2597,7 +2597,7 @@ static QPDFObjectHandle
|
|||||||
added_page(QPDF& pdf, QPDFObjectHandle page)
|
added_page(QPDF& pdf, QPDFObjectHandle page)
|
||||||
{
|
{
|
||||||
QPDFObjectHandle result = page;
|
QPDFObjectHandle result = page;
|
||||||
if (page.getOwningQPDF() != &pdf) {
|
if (page.getOwningQPDF(false) != &pdf) {
|
||||||
// Calling copyForeignObject on an object we already copied
|
// Calling copyForeignObject on an object we already copied
|
||||||
// will give us the already existing copy.
|
// will give us the already existing copy.
|
||||||
result = pdf.copyForeignObject(page);
|
result = pdf.copyForeignObject(page);
|
||||||
|
@ -1207,14 +1207,6 @@ QPDFObjectHandle::getUniqueResourceName(
|
|||||||
" QPDFObjectHandle::getUniqueResourceName");
|
" QPDFObjectHandle::getUniqueResourceName");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indirect object accessors
|
|
||||||
QPDF*
|
|
||||||
QPDFObjectHandle::getOwningQPDF()
|
|
||||||
{
|
|
||||||
// Will be null for direct objects
|
|
||||||
return this->qpdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dictionary mutators
|
// Dictionary mutators
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1634,16 +1626,15 @@ QPDFObjectHandle::coalesceContentStreams()
|
|||||||
// files may have pages that are invalid in other ways.
|
// files may have pages that are invalid in other ways.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QPDF* qpdf = getOwningQPDF();
|
// Should not be possible for a page object to not have an
|
||||||
if (qpdf == nullptr) {
|
// owning PDF unless it was manually constructed in some
|
||||||
// Should not be possible for a page object to not have an
|
// incorrect way. However, it can happen in a PDF file whose
|
||||||
// owning PDF unless it was manually constructed in some
|
// page structure is direct, which is against spec but still
|
||||||
// incorrect way. However, it can happen in a PDF file whose
|
// possible to hand construct, as in fuzz issue 27393.
|
||||||
// page structure is direct, which is against spec but still
|
QPDF* qpdf = getOwningQPDF(
|
||||||
// possible to hand construct, as in fuzz issue 27393.
|
false,
|
||||||
throw std::runtime_error("coalesceContentStreams called on object"
|
"coalesceContentStreams called on object with no associated PDF file");
|
||||||
" with no associated PDF file");
|
|
||||||
}
|
|
||||||
QPDFObjectHandle new_contents = newStream(qpdf);
|
QPDFObjectHandle new_contents = newStream(qpdf);
|
||||||
this->replaceKey("/Contents", new_contents);
|
this->replaceKey("/Contents", new_contents);
|
||||||
|
|
||||||
|
@ -432,7 +432,8 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
|
|||||||
this->oh.replaceKey(
|
this->oh.replaceKey(
|
||||||
"/Contents",
|
"/Contents",
|
||||||
QPDFObjectHandle::newStream(
|
QPDFObjectHandle::newStream(
|
||||||
this->oh.getOwningQPDF(), b.getBufferSharedPointer()));
|
this->oh.getOwningQPDF(false),
|
||||||
|
b.getBufferSharedPointer()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -683,11 +684,10 @@ QPDFPageObjectHelper::removeUnreferencedResources()
|
|||||||
QPDFPageObjectHelper
|
QPDFPageObjectHelper
|
||||||
QPDFPageObjectHelper::shallowCopyPage()
|
QPDFPageObjectHelper::shallowCopyPage()
|
||||||
{
|
{
|
||||||
QPDF* qpdf = this->oh.getOwningQPDF();
|
QPDF* qpdf = this->oh.getOwningQPDF(
|
||||||
if (!qpdf) {
|
false,
|
||||||
throw std::runtime_error("QPDFPageObjectHelper::shallowCopyPage"
|
"QPDFPageObjectHelper::shallowCopyPage called with a direct object");
|
||||||
" called with a direct object");
|
|
||||||
}
|
|
||||||
QPDFObjectHandle new_page = this->oh.shallowCopy();
|
QPDFObjectHandle new_page = this->oh.shallowCopy();
|
||||||
return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
|
return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page));
|
||||||
}
|
}
|
||||||
@ -743,11 +743,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert)
|
|||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
|
QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations)
|
||||||
{
|
{
|
||||||
QPDF* qpdf = this->oh.getOwningQPDF();
|
QPDF* qpdf = this->oh.getOwningQPDF(
|
||||||
if (!qpdf) {
|
false,
|
||||||
throw std::runtime_error("QPDFPageObjectHelper::getFormXObjectForPage"
|
"QPDFPageObjectHelper::getFormXObjectForPage called with a direct "
|
||||||
" called with a direct object");
|
"object");
|
||||||
}
|
|
||||||
QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf);
|
QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf);
|
||||||
QPDFObjectHandle newdict = result.getDict();
|
QPDFObjectHandle newdict = result.getDict();
|
||||||
newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
|
||||||
@ -917,11 +916,9 @@ QPDFPageObjectHelper::placeFormXObject(
|
|||||||
void
|
void
|
||||||
QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
|
QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
|
||||||
{
|
{
|
||||||
QPDF* qpdf = this->oh.getOwningQPDF();
|
QPDF* qpdf = this->oh.getOwningQPDF(
|
||||||
if (!qpdf) {
|
false,
|
||||||
throw std::runtime_error("QPDFPageObjectHelper::flattenRotation"
|
"QPDFPageObjectHelper::flattenRotation called with a direct object");
|
||||||
" called with a direct object");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rotate_oh = this->oh.getKey("/Rotate");
|
auto rotate_oh = this->oh.getKey("/Rotate");
|
||||||
int rotate = 0;
|
int rotate = 0;
|
||||||
@ -1066,16 +1063,12 @@ QPDFPageObjectHelper::copyAnnotations(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF();
|
QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF(
|
||||||
if (!from_qpdf) {
|
false,
|
||||||
throw std::runtime_error("QPDFPageObjectHelper::copyAnnotations:"
|
"QPDFPageObjectHelper::copyAnnotations: from page is a direct object");
|
||||||
" from page is a direct object");
|
QPDF* this_qpdf = this->oh.getOwningQPDF(
|
||||||
}
|
false,
|
||||||
QPDF* this_qpdf = this->oh.getOwningQPDF();
|
"QPDFPageObjectHelper::copyAnnotations: this page is a direct object");
|
||||||
if (!this_qpdf) {
|
|
||||||
throw std::runtime_error("QPDFPageObjectHelper::copyAnnotations:"
|
|
||||||
" this page is a direct object");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QPDFObjectHandle> new_annots;
|
std::vector<QPDFObjectHandle> new_annots;
|
||||||
std::vector<QPDFObjectHandle> new_fields;
|
std::vector<QPDFObjectHandle> new_fields;
|
||||||
|
@ -234,7 +234,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos)
|
|||||||
newpage = makeIndirectObject(newpage);
|
newpage = makeIndirectObject(newpage);
|
||||||
} else if (newpage.getOwningQPDF() != this) {
|
} else if (newpage.getOwningQPDF() != this) {
|
||||||
QTC::TC("qpdf", "QPDF insert foreign page");
|
QTC::TC("qpdf", "QPDF insert foreign page");
|
||||||
newpage.getOwningQPDF()->pushInheritedAttributesToPage();
|
newpage.getOwningQPDF(false)->pushInheritedAttributesToPage();
|
||||||
newpage = copyForeignObject(newpage);
|
newpage = copyForeignObject(newpage);
|
||||||
} else {
|
} else {
|
||||||
QTC::TC("qpdf", "QPDF insert indirect page");
|
QTC::TC("qpdf", "QPDF insert indirect page");
|
||||||
|
Loading…
Reference in New Issue
Block a user