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