Change olist variable in QPDFParser::parse to vector<shared_ptr<QPDFObject>>

This commit is contained in:
m-holger 2022-12-19 11:41:09 +00:00 committed by Jay Berkenbilt
parent e91e642cf3
commit 9da50ca360
6 changed files with 54 additions and 14 deletions

View File

@ -1608,12 +1608,12 @@ class QPDFObjectHandle
QPDF_DLL
bool isImage(bool exclude_imagemask = true);
private:
QPDFObjectHandle(std::shared_ptr<QPDFObject> const& obj) :
obj(obj)
{
}
private:
QPDF_Array* asArray();
QPDF_Bool* asBool();
QPDF_Dictionary* asDictionary();

View File

@ -33,7 +33,7 @@ namespace
{
}
std::vector<QPDFObjectHandle> olist;
std::vector<std::shared_ptr<QPDFObject>> olist;
qpdf_offset_t offset;
std::string contents_string;
qpdf_offset_t contents_offset;
@ -67,7 +67,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
int good_count = 0;
bool b_contents = false;
bool is_null = false;
auto null_oh = QPDFObjectHandle::newNull();
auto null_oh = QPDF_Null::create();
while (!done) {
bool bad = false;
@ -191,11 +191,13 @@ QPDFParser::parse(bool& empty, bool content_stream)
if (content_stream) {
object = QPDF_Operator::create(value);
} else if (
(value == "R") && (state != st_top) && (size >= 2) &&
(!olist.back().isIndirect()) &&
(olist.back().isInteger()) &&
(!olist.at(size - 2).isIndirect()) &&
(olist.at(size - 2).isInteger())) {
value == "R" && state != st_top && size >= 2 &&
olist.back() &&
olist.back()->getTypeCode() == ::ot_integer &&
!olist.back()->getObjGen().isIndirect() &&
olist.at(size - 2) &&
olist.at(size - 2)->getTypeCode() == ::ot_integer &&
!olist.at(size - 2)->getObjGen().isIndirect()) {
if (context == nullptr) {
QTC::TC("qpdf", "QPDFParser indirect without context");
throw std::logic_error(
@ -203,8 +205,8 @@ QPDFParser::parse(bool& empty, bool content_stream)
" on an object with indirect references");
}
auto ref_og = QPDFObjGen(
olist.at(size - 2).getIntValueAsInt(),
olist.back().getIntValueAsInt());
QPDFObjectHandle(olist.at(size - 2)).getIntValueAsInt(),
QPDFObjectHandle(olist.back()).getIntValueAsInt());
if (ref_og.isIndirect()) {
// This action has the desirable side effect
// of causing dangling references (references
@ -306,7 +308,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
setDescription(object, input->getLastOffset());
}
set_offset = true;
olist.push_back(is_null ? null_oh : QPDFObjectHandle(object));
olist.push_back(is_null ? null_oh : object);
break;
case st_top:
@ -325,7 +327,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
parser_state_e old_state = state_stack.back();
state_stack.pop_back();
if (old_state == st_array) {
object = QPDF_Array::create(olist);
object = QPDF_Array::create(std::move(olist));
setDescription(object, offset - 1);
// The `offset` points to the next of "[". Set the rewind
// offset to point to the beginning of "[". This has been
@ -412,8 +414,7 @@ QPDFParser::parse(bool& empty, bool content_stream)
if (state_stack.back() == st_top) {
done = true;
} else {
stack.back().olist.push_back(
is_null ? null_oh : QPDFObjectHandle(object));
stack.back().olist.push_back(is_null ? null_oh : object);
}
}
}

View File

@ -1,6 +1,7 @@
#include <qpdf/QPDF_Array.hh>
#include <qpdf/QIntC.hh>
#include <qpdf/QPDFObject_private.hh>
#include <qpdf/QUtil.hh>
#include <stdexcept>
@ -10,6 +11,12 @@ QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v) :
setFromVector(v);
}
QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v) :
QPDFValue(::ot_array, "array")
{
setFromVector(std::move(v));
}
QPDF_Array::QPDF_Array(SparseOHArray const& items) :
QPDFValue(::ot_array, "array"),
elements(items)
@ -22,6 +29,12 @@ QPDF_Array::create(std::vector<QPDFObjectHandle> const& items)
return do_create(new QPDF_Array(items));
}
std::shared_ptr<QPDFObject>
QPDF_Array::create(std::vector<std::shared_ptr<QPDFObject>>&& items)
{
return do_create(new QPDF_Array(std::move(items)));
}
std::shared_ptr<QPDFObject>
QPDF_Array::create(SparseOHArray const& items)
{
@ -106,6 +119,15 @@ QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
}
}
void
QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v)
{
this->elements = SparseOHArray();
for (auto&& iter: v) {
this->elements.append(iter);
}
}
void
QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
{

View File

@ -1,5 +1,8 @@
#include <qpdf/SparseOHArray.hh>
#include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QPDFObject_private.hh>
#include <stdexcept>
SparseOHArray::SparseOHArray() :
@ -22,6 +25,15 @@ SparseOHArray::append(QPDFObjectHandle oh)
++this->n_elements;
}
void
SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj)
{
if (obj->getTypeCode() != ::ot_null || !obj->getObjGen().isIndirect()) {
this->elements[this->n_elements] = std::move(obj);
}
++this->n_elements;
}
QPDFObjectHandle
SparseOHArray::at(size_t idx) const
{

View File

@ -13,6 +13,8 @@ class QPDF_Array: public QPDFValue
virtual ~QPDF_Array() = default;
static std::shared_ptr<QPDFObject>
create(std::vector<QPDFObjectHandle> const& items);
static std::shared_ptr<QPDFObject>
create(std::vector<std::shared_ptr<QPDFObject>>&& items);
static std::shared_ptr<QPDFObject> create(SparseOHArray const& items);
virtual std::shared_ptr<QPDFObject> copy(bool shallow = false);
virtual std::string unparse();
@ -25,6 +27,7 @@ class QPDF_Array: public QPDFValue
void setItem(int, QPDFObjectHandle const&);
void setFromVector(std::vector<QPDFObjectHandle> const& items);
void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
void insertItem(int at, QPDFObjectHandle const& item);
void appendItem(QPDFObjectHandle const& item);
void eraseItem(int at);
@ -36,6 +39,7 @@ class QPDF_Array: public QPDFValue
private:
QPDF_Array(std::vector<QPDFObjectHandle> const& items);
QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items);
QPDF_Array(SparseOHArray const& items);
SparseOHArray elements;
};

View File

@ -10,6 +10,7 @@ class SparseOHArray
SparseOHArray();
size_t size() const;
void append(QPDFObjectHandle oh);
void append(std::shared_ptr<QPDFObject>&& obj);
QPDFObjectHandle at(size_t idx) const;
void remove_last();
void setAt(size_t idx, QPDFObjectHandle oh);