mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
Use QPDFObjectHandle::asInteger in the library
This commit is contained in:
parent
f2fc1d3db8
commit
6b5fc3278d
112
libqpdf/QPDF.cc
112
libqpdf/QPDF.cc
@ -686,7 +686,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
|
|||||||
if (!m->trailer.isInitialized()) {
|
if (!m->trailer.isInitialized()) {
|
||||||
throw damagedPDF("", 0, "unable to find trailer while reading xref");
|
throw damagedPDF("", 0, "unable to find trailer while reading xref");
|
||||||
}
|
}
|
||||||
int size = m->trailer.getKey("/Size").getIntValueAsInt();
|
int size = m->trailer.getKey("/Size").asInteger();
|
||||||
int max_obj = 0;
|
int max_obj = 0;
|
||||||
if (!m->xref_table.empty()) {
|
if (!m->xref_table.empty()) {
|
||||||
max_obj = (*(m->xref_table.rbegin())).first.getObj();
|
max_obj = (*(m->xref_table.rbegin())).first.getObj();
|
||||||
@ -912,17 +912,13 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_trailer.hasKey("/XRefStm")) {
|
if (!m->ignore_xref_streams) {
|
||||||
if (m->ignore_xref_streams) {
|
if (auto offset = cur_trailer.getKey("/XRefStm").asInteger()) {
|
||||||
QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
|
// Read the xref stream but disregard any return value -- we'll use our trailer's
|
||||||
} else {
|
// /Prev key instead of the xref stream's.
|
||||||
if (cur_trailer.getKey("/XRefStm").isInteger()) {
|
(void)read_xrefStream(offset);
|
||||||
// Read the xref stream but disregard any return value -- we'll use our trailer's
|
} else if (!offset.null()) {
|
||||||
// /Prev key instead of the xref stream's.
|
throw damagedPDF("xref stream", xref_offset, "invalid /XRefStm");
|
||||||
(void)read_xrefStream(cur_trailer.getKey("/XRefStm").getIntValue());
|
|
||||||
} else {
|
|
||||||
throw damagedPDF("xref stream", xref_offset, "invalid /XRefStm");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,15 +927,12 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
|
|||||||
insertFreeXrefEntry(og);
|
insertFreeXrefEntry(og);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_trailer.hasKey("/Prev")) {
|
if (auto prev = cur_trailer.getKey("/Prev").asInteger(true)) {
|
||||||
if (!cur_trailer.getKey("/Prev").isInteger()) {
|
QTC::TC("qpdf", "QPDF prev key in trailer dictionary", prev.null() ? 0 : 1);
|
||||||
QTC::TC("qpdf", "QPDF trailer prev not integer");
|
return prev;
|
||||||
throw damagedPDF("trailer", "/Prev key in trailer dictionary is not an integer");
|
|
||||||
}
|
|
||||||
QTC::TC("qpdf", "QPDF prev key in trailer dictionary");
|
|
||||||
xref_offset = cur_trailer.getKey("/Prev").getIntValue();
|
|
||||||
} else {
|
} else {
|
||||||
xref_offset = 0;
|
QTC::TC("qpdf", "QPDF trailer prev not integer");
|
||||||
|
throw damagedPDF("trailer", "/Prev key in trailer dictionary is not an integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return xref_offset;
|
return xref_offset;
|
||||||
@ -987,7 +980,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
size_t entry_size = 0;
|
size_t entry_size = 0;
|
||||||
int max_bytes = sizeof(qpdf_offset_t);
|
int max_bytes = sizeof(qpdf_offset_t);
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
W[i] = W_obj.getArrayItem(i).getIntValueAsInt();
|
W[i] = W_obj.getArrayItem(i).asInteger();
|
||||||
if (W[i] > max_bytes) {
|
if (W[i] > max_bytes) {
|
||||||
throw damagedPDF(
|
throw damagedPDF(
|
||||||
"xref stream",
|
"xref stream",
|
||||||
@ -1013,8 +1006,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
"values");
|
"values");
|
||||||
}
|
}
|
||||||
for (int i = 0; i < n_index; ++i) {
|
for (int i = 0; i < n_index; ++i) {
|
||||||
if (Index_obj.getArrayItem(i).isInteger()) {
|
if (auto index = Index_obj.getArrayItem(i).asInteger()) {
|
||||||
indx.push_back(Index_obj.getArrayItem(i).getIntValue());
|
indx.emplace_back(index);
|
||||||
} else {
|
} else {
|
||||||
throw damagedPDF(
|
throw damagedPDF(
|
||||||
"xref stream",
|
"xref stream",
|
||||||
@ -1026,9 +1019,8 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1);
|
QTC::TC("qpdf", "QPDF xref /Index is array", n_index == 2 ? 0 : 1);
|
||||||
} else {
|
} else {
|
||||||
QTC::TC("qpdf", "QPDF xref /Index is null");
|
QTC::TC("qpdf", "QPDF xref /Index is null");
|
||||||
long long size = dict.getKey("/Size").getIntValue();
|
indx.emplace_back(0);
|
||||||
indx.push_back(0);
|
indx.emplace_back(dict.getKey("/Size").asInteger());
|
||||||
indx.push_back(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_entries = 0;
|
size_t num_entries = 0;
|
||||||
@ -1131,18 +1123,12 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
setTrailer(dict);
|
setTrailer(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict.hasKey("/Prev")) {
|
if (auto prev = dict.getKey("/Prev").asInteger(true)) {
|
||||||
if (!dict.getKey("/Prev").isInteger()) {
|
|
||||||
throw damagedPDF(
|
|
||||||
"xref stream", "/Prev key in xref stream dictionary is not an integer");
|
|
||||||
}
|
|
||||||
QTC::TC("qpdf", "QPDF prev key in xref stream dictionary");
|
QTC::TC("qpdf", "QPDF prev key in xref stream dictionary");
|
||||||
xref_offset = dict.getKey("/Prev").getIntValue();
|
return prev;
|
||||||
} else {
|
} else {
|
||||||
xref_offset = 0;
|
throw damagedPDF("xref stream", "/Prev key in xref stream dictionary is not an integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
return xref_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1368,25 +1354,22 @@ QPDF::readStream(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset_t offset)
|
|||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto length_obj = object.getKey("/Length");
|
if (auto length_obj = object.getKey("/Length").asInteger()) {
|
||||||
|
length = toS(length_obj.value());
|
||||||
if (!length_obj.isInteger()) {
|
// Seek in two steps to avoid potential integer overflow
|
||||||
if (length_obj.isNull()) {
|
m->file->seek(stream_offset, SEEK_SET);
|
||||||
QTC::TC("qpdf", "QPDF stream without length");
|
m->file->seek(toO(length), SEEK_CUR);
|
||||||
throw damagedPDF(offset, "stream dictionary lacks /Length key");
|
if (!readToken(m->file).isWord("endstream")) {
|
||||||
|
QTC::TC("qpdf", "QPDF missing endstream");
|
||||||
|
throw damagedPDF("expected endstream");
|
||||||
}
|
}
|
||||||
|
} else if (length_obj.null()) {
|
||||||
|
QTC::TC("qpdf", "QPDF stream without length");
|
||||||
|
throw damagedPDF(offset, "stream dictionary lacks /Length key");
|
||||||
|
} else {
|
||||||
QTC::TC("qpdf", "QPDF stream length not integer");
|
QTC::TC("qpdf", "QPDF stream length not integer");
|
||||||
throw damagedPDF(offset, "/Length key in stream dictionary is not an integer");
|
throw damagedPDF(offset, "/Length key in stream dictionary is not an integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
length = toS(length_obj.getUIntValue());
|
|
||||||
// Seek in two steps to avoid potential integer overflow
|
|
||||||
m->file->seek(stream_offset, SEEK_SET);
|
|
||||||
m->file->seek(toO(length), SEEK_CUR);
|
|
||||||
if (!readToken(m->file).isWord("endstream")) {
|
|
||||||
QTC::TC("qpdf", "QPDF missing endstream");
|
|
||||||
throw damagedPDF("expected endstream");
|
|
||||||
}
|
|
||||||
} catch (QPDFExc& e) {
|
} catch (QPDFExc& e) {
|
||||||
if (m->attempt_recovery) {
|
if (m->attempt_recovery) {
|
||||||
warn(e);
|
warn(e);
|
||||||
@ -1778,15 +1761,14 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
|
|||||||
warn(damagedPDF(
|
warn(damagedPDF(
|
||||||
"supposed object stream " + std::to_string(obj_stream_number) + " has wrong type"));
|
"supposed object stream " + std::to_string(obj_stream_number) + " has wrong type"));
|
||||||
}
|
}
|
||||||
|
int n{0};
|
||||||
if (!(dict.getKey("/N").isInteger() && dict.getKey("/First").isInteger())) {
|
long long first{0};
|
||||||
|
if (!(dict.getKey("/N").asInteger().assign_to(n) &&
|
||||||
|
dict.getKey("/First").asInteger().assign_to(first))) {
|
||||||
throw damagedPDF(
|
throw damagedPDF(
|
||||||
("object stream " + std::to_string(obj_stream_number) + " has incorrect keys"));
|
("object stream " + std::to_string(obj_stream_number) + " has incorrect keys"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = dict.getKey("/N").getIntValueAsInt();
|
|
||||||
int first = dict.getKey("/First").getIntValueAsInt();
|
|
||||||
|
|
||||||
std::map<int, int> offsets;
|
std::map<int, int> offsets;
|
||||||
|
|
||||||
std::shared_ptr<Buffer> bp = obj_stream.getStreamData(qpdf_dl_specialized);
|
std::shared_ptr<Buffer> bp = obj_stream.getStreamData(qpdf_dl_specialized);
|
||||||
@ -2328,21 +2310,11 @@ QPDF::getPDFVersion() const
|
|||||||
int
|
int
|
||||||
QPDF::getExtensionLevel()
|
QPDF::getExtensionLevel()
|
||||||
{
|
{
|
||||||
int result = 0;
|
return getRoot()
|
||||||
QPDFObjectHandle obj = getRoot();
|
.getKey("/Extensions")
|
||||||
if (obj.hasKey("/Extensions")) {
|
.getKeyIfDict("/ADBE")
|
||||||
obj = obj.getKey("/Extensions");
|
.getKeyIfDict("/ExtensionLevel")
|
||||||
if (obj.isDictionary() && obj.hasKey("/ADBE")) {
|
.asInteger(true);
|
||||||
obj = obj.getKey("/ADBE");
|
|
||||||
if (obj.isDictionary() && obj.hasKey("/ExtensionLevel")) {
|
|
||||||
obj = obj.getKey("/ExtensionLevel");
|
|
||||||
if (obj.isInteger()) {
|
|
||||||
result = obj.getIntValueAsInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
|
@ -740,9 +740,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
|
|||||||
if (acroform.getKey("/DA").isString()) {
|
if (acroform.getKey("/DA").isString()) {
|
||||||
default_da = acroform.getKey("/DA").getUTF8Value();
|
default_da = acroform.getKey("/DA").getUTF8Value();
|
||||||
}
|
}
|
||||||
if (acroform.getKey("/Q").isInteger()) {
|
acroform.getKey("/Q").asInteger().assign_to(default_q);
|
||||||
default_q = acroform.getKey("/Q").getIntValueAsInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (from_acroform.isDictionary()) {
|
if (from_acroform.isDictionary()) {
|
||||||
if (from_acroform.getKey("/DR").isDictionary()) {
|
if (from_acroform.getKey("/DR").isDictionary()) {
|
||||||
@ -755,9 +753,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
|
|||||||
if (from_acroform.getKey("/DA").isString()) {
|
if (from_acroform.getKey("/DA").isString()) {
|
||||||
from_default_da = from_acroform.getKey("/DA").getUTF8Value();
|
from_default_da = from_acroform.getKey("/DA").getUTF8Value();
|
||||||
}
|
}
|
||||||
if (from_acroform.getKey("/Q").isInteger()) {
|
from_acroform.getKey("/Q").asInteger().assign_to(from_default_q);
|
||||||
from_default_q = from_acroform.getKey("/Q").getIntValueAsInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (from_default_da != default_da) {
|
if (from_default_da != default_da) {
|
||||||
override_da = true;
|
override_da = true;
|
||||||
|
@ -42,8 +42,8 @@ QPDFAnnotationObjectHelper::getAppearanceState()
|
|||||||
int
|
int
|
||||||
QPDFAnnotationObjectHelper::getFlags()
|
QPDFAnnotationObjectHelper::getFlags()
|
||||||
{
|
{
|
||||||
QPDFObjectHandle flags_obj = this->oh.getKey("/F");
|
auto flags_obj = this->oh.getKey("/F").asInteger();
|
||||||
return flags_obj.isInteger() ? flags_obj.getIntValueAsInt() : 0;
|
return flags_obj ? flags_obj : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
|
@ -57,11 +57,8 @@ QPDFEFStreamObjectHelper::getModDate()
|
|||||||
size_t
|
size_t
|
||||||
QPDFEFStreamObjectHelper::getSize()
|
QPDFEFStreamObjectHelper::getSize()
|
||||||
{
|
{
|
||||||
auto val = getParam("/Size");
|
auto val = getParam("/Size").asInteger();
|
||||||
if (val.isInteger()) {
|
return val ? QIntC::to_size(val.value()) : 0;
|
||||||
return QIntC::to_size(val.getUIntValueAsUInt());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
@ -213,25 +213,19 @@ QPDFFormFieldObjectHelper::getDefaultAppearance()
|
|||||||
int
|
int
|
||||||
QPDFFormFieldObjectHelper::getQuadding()
|
QPDFFormFieldObjectHelper::getQuadding()
|
||||||
{
|
{
|
||||||
QPDFObjectHandle fv = getInheritableFieldValue("/Q");
|
if (auto fv = getInheritableFieldValue("/Q").asInteger()) {
|
||||||
bool looked_in_acroform = false;
|
QTC::TC("qpdf", "QPDFFormFieldObjectHelper Q present");
|
||||||
if (!fv.isInteger()) {
|
return fv;
|
||||||
fv = getFieldFromAcroForm("/Q");
|
} else {
|
||||||
looked_in_acroform = true;
|
QTC::TC("qpdf", "QPDFFormFieldObjectHelper Q present looked");
|
||||||
|
return getFieldFromAcroForm("/Q").asInteger(true);
|
||||||
}
|
}
|
||||||
int result = 0;
|
|
||||||
if (fv.isInteger()) {
|
|
||||||
QTC::TC("qpdf", "QPDFFormFieldObjectHelper Q present", looked_in_acroform ? 0 : 1);
|
|
||||||
result = QIntC::to_int(fv.getIntValue());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
QPDFFormFieldObjectHelper::getFlags()
|
QPDFFormFieldObjectHelper::getFlags()
|
||||||
{
|
{
|
||||||
QPDFObjectHandle f = getInheritableFieldValue("/Ff");
|
return getInheritableFieldValue("/Ff").asInteger(true);
|
||||||
return f.isInteger() ? f.getIntValueAsInt() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -130,8 +130,8 @@ ImageOptimizer::makePipeline(std::string const& description, Pipeline* next)
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
QPDFObjectHandle components_obj = dict.getKey("/BitsPerComponent");
|
auto components_obj = dict.getKey("/BitsPerComponent").asInteger();
|
||||||
if (!(components_obj.isInteger() && (components_obj.getIntValue() == 8))) {
|
if (!(components_obj && (components_obj.value() == 8))) {
|
||||||
QTC::TC("qpdf", "QPDFJob image optimize bits per component");
|
QTC::TC("qpdf", "QPDFJob image optimize bits per component");
|
||||||
if (!description.empty()) {
|
if (!description.empty()) {
|
||||||
o.doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
o.doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
||||||
@ -144,14 +144,14 @@ ImageOptimizer::makePipeline(std::string const& description, Pipeline* next)
|
|||||||
// Files have been seen in the wild whose width and height are floating point, which is goofy,
|
// Files have been seen in the wild whose width and height are floating point, which is goofy,
|
||||||
// but we can deal with it.
|
// but we can deal with it.
|
||||||
JDIMENSION w = 0;
|
JDIMENSION w = 0;
|
||||||
if (w_obj.isInteger()) {
|
if (auto w_int = w_obj.asInteger()) {
|
||||||
w = w_obj.getUIntValueAsUInt();
|
w = w_int;
|
||||||
} else {
|
} else {
|
||||||
w = static_cast<JDIMENSION>(w_obj.getNumericValue());
|
w = static_cast<JDIMENSION>(w_obj.getNumericValue());
|
||||||
}
|
}
|
||||||
JDIMENSION h = 0;
|
JDIMENSION h = 0;
|
||||||
if (h_obj.isInteger()) {
|
if (auto h_int = h_obj.asInteger()) {
|
||||||
h = h_obj.getUIntValueAsUInt();
|
h = h_int;
|
||||||
} else {
|
} else {
|
||||||
h = static_cast<JDIMENSION>(h_obj.getNumericValue());
|
h = static_cast<JDIMENSION>(h_obj.getNumericValue());
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ ImageOptimizer::evaluate(std::string const& description)
|
|||||||
if (!image.pipeStreamData(p.get(), 0, qpdf_dl_specialized)) {
|
if (!image.pipeStreamData(p.get(), 0, qpdf_dl_specialized)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
long long orig_length = image.getDict().getKey("/Length").getIntValue();
|
long long orig_length = image.getDict().getKey("/Length").asInteger();
|
||||||
if (c.getCount() >= orig_length) {
|
if (c.getCount() >= orig_length) {
|
||||||
QTC::TC("qpdf", "QPDFJob image optimize no shrink");
|
QTC::TC("qpdf", "QPDFJob image optimize no shrink");
|
||||||
o.doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
o.doIfVerbose([&](Pipeline& v, std::string const& prefix) {
|
||||||
@ -858,8 +858,8 @@ QPDFJob::doShowPages(QPDF& pdf)
|
|||||||
std::string const& name = iter2.first;
|
std::string const& name = iter2.first;
|
||||||
QPDFObjectHandle image = iter2.second;
|
QPDFObjectHandle image = iter2.second;
|
||||||
QPDFObjectHandle dict = image.getDict();
|
QPDFObjectHandle dict = image.getDict();
|
||||||
int width = dict.getKey("/Width").getIntValueAsInt();
|
int width = dict.getKey("/Width").asInteger();
|
||||||
int height = dict.getKey("/Height").getIntValueAsInt();
|
int height = dict.getKey("/Height").asInteger();
|
||||||
cout << " " << name << ": " << image.unparse() << ", " << width << " x "
|
cout << " " << name << ": " << image.unparse() << ", " << width << " x "
|
||||||
<< height << "\n";
|
<< height << "\n";
|
||||||
}
|
}
|
||||||
@ -1651,7 +1651,7 @@ QPDFJob::doInspection(QPDF& pdf)
|
|||||||
}
|
}
|
||||||
if (m->show_npages) {
|
if (m->show_npages) {
|
||||||
QTC::TC("qpdf", "QPDFJob npages");
|
QTC::TC("qpdf", "QPDFJob npages");
|
||||||
cout << pdf.getRoot().getKey("/Pages").getKey("/Count").getIntValue() << "\n";
|
cout << pdf.getRoot().getKey("/Pages").getKey("/Count").asInteger().value() << "\n";
|
||||||
}
|
}
|
||||||
if (m->show_encryption) {
|
if (m->show_encryption) {
|
||||||
showEncryption(pdf);
|
showEncryption(pdf);
|
||||||
@ -3081,10 +3081,9 @@ QPDFJob::writeOutfile(QPDF& pdf)
|
|||||||
try {
|
try {
|
||||||
QUtil::remove_file(backup.c_str());
|
QUtil::remove_file(backup.c_str());
|
||||||
} catch (QPDFSystemError& e) {
|
} catch (QPDFSystemError& e) {
|
||||||
*m->log->getError()
|
*m->log->getError() << m->message_prefix << ": unable to delete original file ("
|
||||||
<< m->message_prefix << ": unable to delete original file (" << e.what() << ");"
|
<< e.what() << ");" << " original file left in " << backup
|
||||||
<< " original file left in " << backup
|
<< ", but the input was successfully replaced\n";
|
||||||
<< ", but the input was successfully replaced\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,14 @@ namespace
|
|||||||
int
|
int
|
||||||
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
|
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
|
||||||
{
|
{
|
||||||
if (!(keyValid(a) && keyValid(b))) {
|
auto ai = a.asInteger();
|
||||||
|
auto bi = b.asInteger();
|
||||||
|
if (!(ai && bi)) {
|
||||||
// We don't call this without calling keyValid first
|
// We don't call this without calling keyValid first
|
||||||
throw std::logic_error("comparing invalid keys");
|
throw std::logic_error("comparing invalid keys");
|
||||||
}
|
}
|
||||||
auto as = a.getIntValue();
|
auto as = ai.value();
|
||||||
auto bs = b.getIntValue();
|
auto bs = bi.value();
|
||||||
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
|
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -91,7 +93,7 @@ QPDFNumberTreeObjectHelper::iterator::updateIValue()
|
|||||||
{
|
{
|
||||||
if (impl->valid()) {
|
if (impl->valid()) {
|
||||||
auto p = *impl;
|
auto p = *impl;
|
||||||
this->ivalue.first = p->first.getIntValue();
|
this->ivalue.first = p->first.asInteger();
|
||||||
this->ivalue.second = p->second;
|
this->ivalue.second = p->second;
|
||||||
} else {
|
} else {
|
||||||
this->ivalue.first = 0;
|
this->ivalue.first = 0;
|
||||||
|
@ -83,11 +83,7 @@ QPDFOutlineObjectHelper::getDestPage()
|
|||||||
int
|
int
|
||||||
QPDFOutlineObjectHelper::getCount()
|
QPDFOutlineObjectHelper::getCount()
|
||||||
{
|
{
|
||||||
int count = 0;
|
return this->oh.getKey("/Count").asInteger(true);
|
||||||
if (this->oh.hasKey("/Count")) {
|
|
||||||
count = this->oh.getKey("/Count").getIntValueAsInt();
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
|
@ -88,11 +88,7 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
|
|||||||
std::vector<QPDFAnnotationObjectHelper> annots = page.getAnnotations();
|
std::vector<QPDFAnnotationObjectHelper> annots = page.getAnnotations();
|
||||||
std::vector<QPDFObjectHandle> new_annots;
|
std::vector<QPDFObjectHandle> new_annots;
|
||||||
std::string new_content;
|
std::string new_content;
|
||||||
int rotate = 0;
|
int rotate = page.getObjectHandle().getKey("/Rotate").asInteger(true);
|
||||||
QPDFObjectHandle rotate_obj = page.getObjectHandle().getKey("/Rotate");
|
|
||||||
if (rotate_obj.isInteger() && rotate_obj.getIntValue()) {
|
|
||||||
rotate = rotate_obj.getIntValueAsInt();
|
|
||||||
}
|
|
||||||
int next_fx = 1;
|
int next_fx = 1;
|
||||||
for (auto& aoh: annots) {
|
for (auto& aoh: annots) {
|
||||||
QPDFObjectHandle as = aoh.getAppearanceStream("/N");
|
QPDFObjectHandle as = aoh.getAppearanceStream("/N");
|
||||||
|
@ -36,11 +36,8 @@ QPDFPageLabelDocumentHelper::getLabelForPage(long long page_idx)
|
|||||||
}
|
}
|
||||||
QPDFObjectHandle S = label.getKey("/S"); // type (D, R, r, A, a)
|
QPDFObjectHandle S = label.getKey("/S"); // type (D, R, r, A, a)
|
||||||
QPDFObjectHandle P = label.getKey("/P"); // prefix
|
QPDFObjectHandle P = label.getKey("/P"); // prefix
|
||||||
QPDFObjectHandle St = label.getKey("/St"); // starting number
|
auto St = label.getKey("/St").asInteger(); // starting number
|
||||||
long long start = 1;
|
long long start = St ? St : 1;
|
||||||
if (St.isInteger()) {
|
|
||||||
start = St.getIntValue();
|
|
||||||
}
|
|
||||||
QIntC::range_check(start, offset);
|
QIntC::range_check(start, offset);
|
||||||
start += offset;
|
start += offset;
|
||||||
result = QPDFObjectHandle::newDictionary();
|
result = QPDFObjectHandle::newDictionary();
|
||||||
@ -72,14 +69,14 @@ QPDFPageLabelDocumentHelper::getLabelsForPageRange(
|
|||||||
bool skip_first = false;
|
bool skip_first = false;
|
||||||
if (size >= 2) {
|
if (size >= 2) {
|
||||||
QPDFObjectHandle last = new_labels.at(size - 1);
|
QPDFObjectHandle last = new_labels.at(size - 1);
|
||||||
QPDFObjectHandle last_idx = new_labels.at(size - 2);
|
auto last_idx = new_labels.at(size - 2).asInteger();
|
||||||
if (last_idx.isInteger() && last.isDictionary() &&
|
auto st = label.getKey("/St").asInteger();
|
||||||
|
auto last_st = last.getKey("/St").asInteger();
|
||||||
|
if (last_idx && last.isDictionary() &&
|
||||||
(label.getKey("/S").unparse() == last.getKey("/S").unparse()) &&
|
(label.getKey("/S").unparse() == last.getKey("/S").unparse()) &&
|
||||||
(label.getKey("/P").unparse() == last.getKey("/P").unparse()) &&
|
(label.getKey("/P").unparse() == last.getKey("/P").unparse()) && st && last_st) {
|
||||||
label.getKey("/St").isInteger() && last.getKey("/St").isInteger()) {
|
auto st_delta = st.value() - last_st.value();
|
||||||
long long int st_delta =
|
auto idx_delta = new_start_idx - last_idx.value();
|
||||||
label.getKey("/St").getIntValue() - last.getKey("/St").getIntValue();
|
|
||||||
long long int idx_delta = new_start_idx - last_idx.getIntValue();
|
|
||||||
if (st_delta == idx_delta) {
|
if (st_delta == idx_delta) {
|
||||||
QTC::TC("qpdf", "QPDFPageLabelDocumentHelper skip first");
|
QTC::TC("qpdf", "QPDFPageLabelDocumentHelper skip first");
|
||||||
skip_first = true;
|
skip_first = true;
|
||||||
|
@ -667,14 +667,14 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert)
|
|||||||
if (!bbox.isRectangle()) {
|
if (!bbox.isRectangle()) {
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
QPDFObjectHandle rotate_obj = getAttribute("/Rotate", false);
|
auto rotate_obj = getAttribute("/Rotate", false).asInteger();
|
||||||
QPDFObjectHandle scale_obj = getAttribute("/UserUnit", false);
|
QPDFObjectHandle scale_obj = getAttribute("/UserUnit", false);
|
||||||
if (!(rotate_obj.isNull() && scale_obj.isNull())) {
|
if (!(rotate_obj.null() && scale_obj.isNull())) {
|
||||||
QPDFObjectHandle::Rectangle rect = bbox.getArrayAsRectangle();
|
QPDFObjectHandle::Rectangle rect = bbox.getArrayAsRectangle();
|
||||||
double width = rect.urx - rect.llx;
|
double width = rect.urx - rect.llx;
|
||||||
double height = rect.ury - rect.lly;
|
double height = rect.ury - rect.lly;
|
||||||
double scale = (scale_obj.isNumber() ? scale_obj.getNumericValue() : 1.0);
|
double scale = (scale_obj.isNumber() ? scale_obj.getNumericValue() : 1.0);
|
||||||
int rotate = (rotate_obj.isInteger() ? rotate_obj.getIntValueAsInt() : 0);
|
int rotate = rotate_obj ? rotate_obj : 0;
|
||||||
if (invert) {
|
if (invert) {
|
||||||
if (scale == 0.0) {
|
if (scale == 0.0) {
|
||||||
return matrix;
|
return matrix;
|
||||||
@ -863,12 +863,9 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh)
|
|||||||
{
|
{
|
||||||
QPDF& qpdf =
|
QPDF& qpdf =
|
||||||
this->oh.getQPDF("QPDFPageObjectHelper::flattenRotation called with a direct object");
|
this->oh.getQPDF("QPDFPageObjectHelper::flattenRotation called with a direct object");
|
||||||
auto rotate_oh = this->oh.getKey("/Rotate");
|
auto rotate_key = this->oh.getKey("/Rotate").asInteger();
|
||||||
int rotate = 0;
|
int rotate = rotate_key ? rotate_key : 0;
|
||||||
if (rotate_oh.isInteger()) {
|
if (!(rotate == 90 || rotate == 180 || rotate == 270)) {
|
||||||
rotate = rotate_oh.getIntValueAsInt();
|
|
||||||
}
|
|
||||||
if (!((rotate == 90) || (rotate == 180) || (rotate == 270))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto mediabox = this->oh.getKey("/MediaBox");
|
auto mediabox = this->oh.getKey("/MediaBox");
|
||||||
|
@ -656,10 +656,11 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
|
|||||||
generateID();
|
generateID();
|
||||||
m->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
|
m->id1 = trailer.getKey("/ID").getArrayItem(0).getStringValue();
|
||||||
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
|
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
|
||||||
int V = encrypt.getKey("/V").getIntValueAsInt();
|
int V = encrypt.getKey("/V").asInteger();
|
||||||
int key_len = 5;
|
int key_len = 5;
|
||||||
if (V > 1) {
|
if (V > 1) {
|
||||||
key_len = encrypt.getKey("/Length").getIntValueAsInt() / 8;
|
key_len = encrypt.getKey("/Length").asInteger();
|
||||||
|
key_len /= 8;
|
||||||
}
|
}
|
||||||
if (encrypt.hasKey("/EncryptMetadata") && encrypt.getKey("/EncryptMetadata").isBool()) {
|
if (encrypt.hasKey("/EncryptMetadata") && encrypt.getKey("/EncryptMetadata").isBool()) {
|
||||||
m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue();
|
m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue();
|
||||||
@ -687,9 +688,9 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf)
|
|||||||
|
|
||||||
setEncryptionParametersInternal(
|
setEncryptionParametersInternal(
|
||||||
V,
|
V,
|
||||||
encrypt.getKey("/R").getIntValueAsInt(),
|
encrypt.getKey("/R").asInteger(),
|
||||||
key_len,
|
key_len,
|
||||||
static_cast<int>(encrypt.getKey("/P").getIntValue()),
|
static_cast<int>(encrypt.getKey("/P").asInteger().value()),
|
||||||
encrypt.getKey("/O").getStringValue(),
|
encrypt.getKey("/O").getStringValue(),
|
||||||
encrypt.getKey("/U").getStringValue(),
|
encrypt.getKey("/U").getStringValue(),
|
||||||
OE,
|
OE,
|
||||||
@ -1416,10 +1417,10 @@ QPDFWriter::unparseObject(
|
|||||||
if (extensions.isInitialized()) {
|
if (extensions.isInitialized()) {
|
||||||
QTC::TC("qpdf", "QPDFWriter preserve Extensions");
|
QTC::TC("qpdf", "QPDFWriter preserve Extensions");
|
||||||
QPDFObjectHandle adbe = extensions.getKey("/ADBE");
|
QPDFObjectHandle adbe = extensions.getKey("/ADBE");
|
||||||
|
auto ext_level = adbe.getKeyIfDict("/ExtensionLevel").asInteger();
|
||||||
if (adbe.isDictionary() &&
|
if (adbe.isDictionary() &&
|
||||||
adbe.getKey("/BaseVersion").isNameAndEquals("/" + m->final_pdf_version) &&
|
adbe.getKey("/BaseVersion").isNameAndEquals("/" + m->final_pdf_version) &&
|
||||||
adbe.getKey("/ExtensionLevel").isInteger() &&
|
ext_level && (static_cast<int>(ext_level) == m->final_extension_level)) {
|
||||||
(adbe.getKey("/ExtensionLevel").getIntValue() == m->final_extension_level)) {
|
|
||||||
QTC::TC("qpdf", "QPDFWriter preserve ADBE");
|
QTC::TC("qpdf", "QPDFWriter preserve ADBE");
|
||||||
} else {
|
} else {
|
||||||
if (need_extensions_adbe) {
|
if (need_extensions_adbe) {
|
||||||
|
@ -586,7 +586,7 @@ QPDF_Stream::pipeStreamData(
|
|||||||
qpdf_offset_t actual_length = count.getCount();
|
qpdf_offset_t actual_length = count.getCount();
|
||||||
qpdf_offset_t desired_length = 0;
|
qpdf_offset_t desired_length = 0;
|
||||||
if (success && this->stream_dict.hasKey("/Length")) {
|
if (success && this->stream_dict.hasKey("/Length")) {
|
||||||
desired_length = this->stream_dict.getKey("/Length").getIntValue();
|
desired_length = this->stream_dict.getKey("/Length").asInteger();
|
||||||
if (actual_length == desired_length) {
|
if (actual_length == desired_length) {
|
||||||
QTC::TC("qpdf", "QPDF_Stream pipe use stream provider");
|
QTC::TC("qpdf", "QPDF_Stream pipe use stream provider");
|
||||||
} else {
|
} else {
|
||||||
|
@ -766,21 +766,22 @@ QPDF::initializeEncryption()
|
|||||||
m->file->getLastOffset(),
|
m->file->getLastOffset(),
|
||||||
"file uses encryption SubFilters, which qpdf does not support");
|
"file uses encryption SubFilters, which qpdf does not support");
|
||||||
}
|
}
|
||||||
|
int V{0};
|
||||||
if (!(encryption_dict.getKey("/V").isInteger() && encryption_dict.getKey("/R").isInteger() &&
|
int R{0};
|
||||||
|
long long p_temp{0};
|
||||||
|
if (!(encryption_dict.getKey("/V").asInteger().assign_to(V) &&
|
||||||
|
encryption_dict.getKey("/R").asInteger().assign_to(R) &&
|
||||||
encryption_dict.getKey("/O").isString() && encryption_dict.getKey("/U").isString() &&
|
encryption_dict.getKey("/O").isString() && encryption_dict.getKey("/U").isString() &&
|
||||||
encryption_dict.getKey("/P").isInteger())) {
|
encryption_dict.getKey("/P").asInteger().assign_to(p_temp))) {
|
||||||
throw damagedPDF(
|
throw damagedPDF(
|
||||||
"encryption dictionary",
|
"encryption dictionary",
|
||||||
"some encryption dictionary parameters are missing or the wrong "
|
"some encryption dictionary parameters are missing or the wrong "
|
||||||
"type");
|
"type");
|
||||||
}
|
}
|
||||||
|
|
||||||
int V = encryption_dict.getKey("/V").getIntValueAsInt();
|
|
||||||
int R = encryption_dict.getKey("/R").getIntValueAsInt();
|
|
||||||
std::string O = encryption_dict.getKey("/O").getStringValue();
|
std::string O = encryption_dict.getKey("/O").getStringValue();
|
||||||
std::string U = encryption_dict.getKey("/U").getStringValue();
|
std::string U = encryption_dict.getKey("/U").getStringValue();
|
||||||
int P = static_cast<int>(encryption_dict.getKey("/P").getIntValue());
|
int P = static_cast<int>(p_temp);
|
||||||
|
|
||||||
// If supporting new encryption R/V values, remember to update error message inside this if
|
// If supporting new encryption R/V values, remember to update error message inside this if
|
||||||
// statement.
|
// statement.
|
||||||
@ -840,8 +841,8 @@ QPDF::initializeEncryption()
|
|||||||
} else if (V == 5) {
|
} else if (V == 5) {
|
||||||
Length = 256;
|
Length = 256;
|
||||||
} else {
|
} else {
|
||||||
if (encryption_dict.getKey("/Length").isInteger()) {
|
if (auto l = encryption_dict.getKey("/Length").asInteger()) {
|
||||||
Length = encryption_dict.getKey("/Length").getIntValueAsInt();
|
Length = l;
|
||||||
if ((Length % 8) || (Length < 40) || (Length > 128)) {
|
if ((Length % 8) || (Length < 40) || (Length > 128)) {
|
||||||
Length = 0;
|
Length = 0;
|
||||||
}
|
}
|
||||||
@ -1249,12 +1250,9 @@ QPDF::isEncrypted(
|
|||||||
if (m->encp->encrypted) {
|
if (m->encp->encrypted) {
|
||||||
QPDFObjectHandle trailer = getTrailer();
|
QPDFObjectHandle trailer = getTrailer();
|
||||||
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
|
QPDFObjectHandle encrypt = trailer.getKey("/Encrypt");
|
||||||
QPDFObjectHandle Pkey = encrypt.getKey("/P");
|
P = static_cast<int>(static_cast<long long>(encrypt.getKey("/P").asInteger()));
|
||||||
QPDFObjectHandle Rkey = encrypt.getKey("/R");
|
R = encrypt.getKey("/R").asInteger();
|
||||||
QPDFObjectHandle Vkey = encrypt.getKey("/V");
|
V = encrypt.getKey("/V").asInteger();
|
||||||
P = static_cast<int>(Pkey.getIntValue());
|
|
||||||
R = Rkey.getIntValueAsInt();
|
|
||||||
V = Vkey.getIntValueAsInt();
|
|
||||||
stream_method = m->encp->cf_stream;
|
stream_method = m->encp->cf_stream;
|
||||||
string_method = m->encp->cf_string;
|
string_method = m->encp->cf_string;
|
||||||
file_method = m->encp->cf_file;
|
file_method = m->encp->cf_file;
|
||||||
|
@ -138,9 +138,8 @@ QPDF::isLinearized()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle L = candidate.getKey("/L");
|
if (auto L = candidate.getKey("/L").asInteger()) {
|
||||||
if (L.isInteger()) {
|
qpdf_offset_t Li = L;
|
||||||
qpdf_offset_t Li = L.getIntValue();
|
|
||||||
m->file->seek(0, SEEK_END);
|
m->file->seek(0, SEEK_END);
|
||||||
if (Li != m->file->tell()) {
|
if (Li != m->file->tell()) {
|
||||||
QTC::TC("qpdf", "QPDF /L mismatch");
|
QTC::TC("qpdf", "QPDF /L mismatch");
|
||||||
@ -168,30 +167,28 @@ QPDF::readLinearizationData()
|
|||||||
|
|
||||||
// /L is read and stored in linp by isLinearized()
|
// /L is read and stored in linp by isLinearized()
|
||||||
QPDFObjectHandle H = m->lindict.getKey("/H");
|
QPDFObjectHandle H = m->lindict.getKey("/H");
|
||||||
QPDFObjectHandle O = m->lindict.getKey("/O");
|
auto O = m->lindict.getKey("/O").asInteger();
|
||||||
QPDFObjectHandle E = m->lindict.getKey("/E");
|
auto E = m->lindict.getKey("/E").asInteger();
|
||||||
QPDFObjectHandle N = m->lindict.getKey("/N");
|
auto N = m->lindict.getKey("/N").asInteger();
|
||||||
QPDFObjectHandle T = m->lindict.getKey("/T");
|
auto T = m->lindict.getKey("/T").asInteger();
|
||||||
QPDFObjectHandle P = m->lindict.getKey("/P");
|
auto P = m->lindict.getKey("/P").asInteger(true);
|
||||||
|
|
||||||
if (!(H.isArray() && O.isInteger() && E.isInteger() && N.isInteger() && T.isInteger() &&
|
if (!(H.isArray() && O && E && N && T && P)) {
|
||||||
(P.isInteger() || P.isNull()))) {
|
|
||||||
throw damagedPDF(
|
throw damagedPDF(
|
||||||
"linearization dictionary",
|
"linearization dictionary",
|
||||||
"some keys in linearization dictionary are of the wrong type");
|
"some keys in linearization dictionary are of the wrong type");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hint table array: offset length [ offset length ]
|
// Hint table array: offset length [ offset length ]
|
||||||
size_t n_H_items = toS(H.getArrayNItems());
|
int n_H_items = H.getArrayNItems();
|
||||||
if (!((n_H_items == 2) || (n_H_items == 4))) {
|
if (!((n_H_items == 2) || (n_H_items == 4))) {
|
||||||
throw damagedPDF("linearization dictionary", "H has the wrong number of items");
|
throw damagedPDF("linearization dictionary", "H has the wrong number of items");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> H_items;
|
std::vector<int> H_items;
|
||||||
for (size_t i = 0; i < n_H_items; ++i) {
|
for (int i = 0; i < n_H_items; ++i) {
|
||||||
QPDFObjectHandle oh(H.getArrayItem(toI(i)));
|
if (auto h = H.getArrayItem(toI(i)).asInteger()) {
|
||||||
if (oh.isInteger()) {
|
H_items.push_back(h);
|
||||||
H_items.push_back(oh.getIntValueAsInt());
|
|
||||||
} else {
|
} else {
|
||||||
throw damagedPDF("linearization dictionary", "some H items are of the wrong type");
|
throw damagedPDF("linearization dictionary", "some H items are of the wrong type");
|
||||||
}
|
}
|
||||||
@ -211,28 +208,22 @@ QPDF::readLinearizationData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// P: first page number
|
// P: first page number
|
||||||
int first_page = 0;
|
QTC::TC("qpdf", "QPDF P present in lindict", P.null() ? 0 : 1);
|
||||||
if (P.isInteger()) {
|
|
||||||
QTC::TC("qpdf", "QPDF P present in lindict");
|
|
||||||
first_page = P.getIntValueAsInt();
|
|
||||||
} else {
|
|
||||||
QTC::TC("qpdf", "QPDF P absent in lindict");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store linearization parameter data
|
// Store linearization parameter data
|
||||||
|
|
||||||
// Various places in the code use linp.npages, which is initialized from N, to pre-allocate
|
// Various places in the code use linp.npages, which is initialized from N, to pre-allocate
|
||||||
// memory, so make sure it's accurate and bail right now if it's not.
|
// memory, so make sure it's accurate and bail right now if it's not.
|
||||||
if (N.getIntValue() != static_cast<long long>(getAllPages().size())) {
|
if (static_cast<long long>(N) != static_cast<long long>(getAllPages().size())) {
|
||||||
throw damagedPDF("linearization hint table", "/N does not match number of pages");
|
throw damagedPDF("linearization hint table", "/N does not match number of pages");
|
||||||
}
|
}
|
||||||
|
|
||||||
// file_size initialized by isLinearized()
|
// file_size initialized by isLinearized()
|
||||||
m->linp.first_page_object = O.getIntValueAsInt();
|
m->linp.first_page_object = O;
|
||||||
m->linp.first_page_end = E.getIntValue();
|
m->linp.first_page_end = E;
|
||||||
m->linp.npages = N.getIntValueAsInt();
|
m->linp.npages = N;
|
||||||
m->linp.xref_zero_offset = T.getIntValue();
|
m->linp.xref_zero_offset = T;
|
||||||
m->linp.first_page = first_page;
|
m->linp.first_page = P;
|
||||||
m->linp.H_offset = H0_offset;
|
m->linp.H_offset = H0_offset;
|
||||||
m->linp.H_length = H0_length;
|
m->linp.H_length = H0_length;
|
||||||
|
|
||||||
@ -255,8 +246,8 @@ QPDF::readLinearizationData()
|
|||||||
// /L page label
|
// /L page label
|
||||||
|
|
||||||
// Individual hint table offsets
|
// Individual hint table offsets
|
||||||
QPDFObjectHandle HS = H0.getKey("/S"); // shared object
|
int HS = H0.getKey("/S").asInteger(); // shared object
|
||||||
QPDFObjectHandle HO = H0.getKey("/O"); // outline
|
auto HO = H0.getKey("/O").asInteger(); // outline
|
||||||
|
|
||||||
auto hbp = pb.getBufferSharedPointer();
|
auto hbp = pb.getBufferSharedPointer();
|
||||||
Buffer* hb = hbp.get();
|
Buffer* hb = hbp.get();
|
||||||
@ -265,18 +256,18 @@ QPDF::readLinearizationData()
|
|||||||
|
|
||||||
readHPageOffset(BitStream(h_buf, h_size));
|
readHPageOffset(BitStream(h_buf, h_size));
|
||||||
|
|
||||||
int HSi = HS.getIntValueAsInt();
|
if ((HS < 0) || (toS(HS) >= h_size)) {
|
||||||
if ((HSi < 0) || (toS(HSi) >= h_size)) {
|
|
||||||
throw damagedPDF("linearization hint table", "/S (shared object) offset is out of bounds");
|
throw damagedPDF("linearization hint table", "/S (shared object) offset is out of bounds");
|
||||||
}
|
}
|
||||||
readHSharedObject(BitStream(h_buf + HSi, h_size - toS(HSi)));
|
readHSharedObject(BitStream(h_buf + HS, h_size - toS(HS)));
|
||||||
|
|
||||||
if (HO.isInteger()) {
|
if (HO) {
|
||||||
int HOi = HO.getIntValueAsInt();
|
int HOi = HO;
|
||||||
if ((HOi < 0) || (toS(HOi) >= h_size)) {
|
auto HOs = toS(HOi);
|
||||||
|
if (HOi < 0 || HOs >= h_size) {
|
||||||
throw damagedPDF("linearization hint table", "/O (outline) offset is out of bounds");
|
throw damagedPDF("linearization hint table", "/O (outline) offset is out of bounds");
|
||||||
}
|
}
|
||||||
readHGeneric(BitStream(h_buf + HOi, h_size - toS(HOi)), m->outline_hints);
|
readHGeneric(BitStream(h_buf + HOi, h_size - HOs), m->outline_hints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +294,7 @@ QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length)
|
|||||||
if (length_obj.isIndirect()) {
|
if (length_obj.isIndirect()) {
|
||||||
QTC::TC("qpdf", "QPDF hint table length indirect");
|
QTC::TC("qpdf", "QPDF hint table length indirect");
|
||||||
// Force resolution
|
// Force resolution
|
||||||
(void)length_obj.getIntValue();
|
(void)length_obj.isInteger();
|
||||||
ObjCache& oc2 = m->obj_cache[length_obj.getObjGen()];
|
ObjCache& oc2 = m->obj_cache[length_obj.getObjGen()];
|
||||||
min_end_offset = oc2.end_before_space;
|
min_end_offset = oc2.end_before_space;
|
||||||
max_end_offset = oc2.end_after_space;
|
max_end_offset = oc2.end_after_space;
|
||||||
|
@ -290,7 +290,7 @@ QPDF::addPage(QPDFObjectHandle newpage, bool first)
|
|||||||
if (first) {
|
if (first) {
|
||||||
insertPage(newpage, 0);
|
insertPage(newpage, 0);
|
||||||
} else {
|
} else {
|
||||||
insertPage(newpage, getRoot().getKey("/Pages").getKey("/Count").getIntValueAsInt());
|
insertPage(newpage, getRoot().getKey("/Pages").getKey("/Count").asInteger());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms)
|
|||||||
bool filterable = true;
|
bool filterable = true;
|
||||||
std::set<std::string> keys = decode_parms.getKeys();
|
std::set<std::string> keys = decode_parms.getKeys();
|
||||||
for (auto const& key: keys) {
|
for (auto const& key: keys) {
|
||||||
QPDFObjectHandle value = decode_parms.getKey(key);
|
auto value = decode_parms.getKey(key).asInteger();
|
||||||
if (key == "/Predictor") {
|
if (key == "/Predictor") {
|
||||||
if (value.isInteger()) {
|
if (value) {
|
||||||
this->predictor = value.getIntValueAsInt();
|
this->predictor = value;
|
||||||
if (!((this->predictor == 1) || (this->predictor == 2) ||
|
if (!((this->predictor == 1) || (this->predictor == 2) ||
|
||||||
((this->predictor >= 10) && (this->predictor <= 15)))) {
|
((this->predictor >= 10) && (this->predictor <= 15)))) {
|
||||||
filterable = false;
|
filterable = false;
|
||||||
@ -40,23 +40,22 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms)
|
|||||||
filterable = false;
|
filterable = false;
|
||||||
}
|
}
|
||||||
} else if ((key == "/Columns") || (key == "/Colors") || (key == "/BitsPerComponent")) {
|
} else if ((key == "/Columns") || (key == "/Colors") || (key == "/BitsPerComponent")) {
|
||||||
if (value.isInteger()) {
|
if (value) {
|
||||||
int val = value.getIntValueAsInt();
|
|
||||||
if (key == "/Columns") {
|
if (key == "/Columns") {
|
||||||
this->columns = val;
|
this->columns = value;
|
||||||
} else if (key == "/Colors") {
|
} else if (key == "/Colors") {
|
||||||
this->colors = val;
|
this->colors = value;
|
||||||
} else if (key == "/BitsPerComponent") {
|
} else if (key == "/BitsPerComponent") {
|
||||||
this->bits_per_component = val;
|
this->bits_per_component = value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filterable = false;
|
filterable = false;
|
||||||
}
|
}
|
||||||
} else if (lzw && (key == "/EarlyChange")) {
|
} else if (lzw && (key == "/EarlyChange")) {
|
||||||
if (value.isInteger()) {
|
if (value) {
|
||||||
int earlychange = value.getIntValueAsInt();
|
int earlychange = value;
|
||||||
this->early_code_change = (earlychange == 1);
|
this->early_code_change = (earlychange == 1);
|
||||||
if (!((earlychange == 0) || (earlychange == 1))) {
|
if (!(earlychange == 0 || earlychange == 1)) {
|
||||||
filterable = false;
|
filterable = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,8 +6,7 @@ QPDF check generation 1
|
|||||||
QPDF check obj 1
|
QPDF check obj 1
|
||||||
QPDF hint table length indirect 0
|
QPDF hint table length indirect 0
|
||||||
QPDF hint table length direct 0
|
QPDF hint table length direct 0
|
||||||
QPDF P absent in lindict 0
|
QPDF P present in lindict 1
|
||||||
QPDF P present in lindict 0
|
|
||||||
QPDF expected n n obj 0
|
QPDF expected n n obj 0
|
||||||
QPDF /L mismatch 0
|
QPDF /L mismatch 0
|
||||||
QPDF err /T mismatch 0
|
QPDF err /T mismatch 0
|
||||||
@ -79,9 +78,8 @@ QPDFObjectHandle makeDirect loop 0
|
|||||||
QPDFObjectHandle copy stream 1
|
QPDFObjectHandle copy stream 1
|
||||||
QPDF default for xref stream field 0 0
|
QPDF default for xref stream field 0 0
|
||||||
QPDF prev key in xref stream dictionary 0
|
QPDF prev key in xref stream dictionary 0
|
||||||
QPDF prev key in trailer dictionary 0
|
QPDF prev key in trailer dictionary 1
|
||||||
QPDF found xref stream 0
|
QPDF found xref stream 0
|
||||||
QPDF ignoring XRefStm in trailer 0
|
|
||||||
QPDF xref deleted object 0
|
QPDF xref deleted object 0
|
||||||
SF_FlateLzwDecode PNG filter 0
|
SF_FlateLzwDecode PNG filter 0
|
||||||
QPDF xref /Index is null 0
|
QPDF xref /Index is null 0
|
||||||
@ -332,7 +330,8 @@ QPDFFormFieldObjectHelper TU present 0
|
|||||||
QPDFFormFieldObjectHelper TM present 0
|
QPDFFormFieldObjectHelper TM present 0
|
||||||
QPDFFormFieldObjectHelper TU absent 0
|
QPDFFormFieldObjectHelper TU absent 0
|
||||||
QPDFFormFieldObjectHelper TM absent 0
|
QPDFFormFieldObjectHelper TM absent 0
|
||||||
QPDFFormFieldObjectHelper Q present 1
|
QPDFFormFieldObjectHelper Q present 0
|
||||||
|
QPDFFormFieldObjectHelper Q present looked 0
|
||||||
QPDFFormFieldObjectHelper DA present 1
|
QPDFFormFieldObjectHelper DA present 1
|
||||||
QPDFAnnotationObjectHelper AS present 0
|
QPDFAnnotationObjectHelper AS present 0
|
||||||
QPDFAnnotationObjectHelper AS absent 0
|
QPDFAnnotationObjectHelper AS absent 0
|
||||||
|
Loading…
Reference in New Issue
Block a user