mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-09 23:00:57 +00:00
Refactor QPDF::procesXRefStream
Add closure damaged to create damagedPDF exceptions.
This commit is contained in:
parent
1737902a5e
commit
7aa5027bf8
@ -971,16 +971,17 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset)
|
|||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
||||||
{
|
{
|
||||||
QPDFObjectHandle dict = xref_obj.getDict();
|
auto damaged = [this, xref_offset](std::string_view msg) -> QPDFExc {
|
||||||
QPDFObjectHandle W_obj = dict.getKey("/W");
|
return damagedPDF("xref stream", xref_offset, msg.data());
|
||||||
QPDFObjectHandle Index_obj = dict.getKey("/Index");
|
};
|
||||||
|
|
||||||
|
auto dict = xref_obj.getDict();
|
||||||
|
auto W_obj = dict.getKey("/W");
|
||||||
|
auto Index_obj = dict.getKey("/Index");
|
||||||
if (!(W_obj.isArray() && (W_obj.getArrayNItems() >= 3) && W_obj.getArrayItem(0).isInteger() &&
|
if (!(W_obj.isArray() && (W_obj.getArrayNItems() >= 3) && W_obj.getArrayItem(0).isInteger() &&
|
||||||
W_obj.getArrayItem(1).isInteger() && W_obj.getArrayItem(2).isInteger() &&
|
W_obj.getArrayItem(1).isInteger() && W_obj.getArrayItem(2).isInteger() &&
|
||||||
dict.getKey("/Size").isInteger() && (Index_obj.isArray() || Index_obj.isNull()))) {
|
dict.getKey("/Size").isInteger() && (Index_obj.isArray() || Index_obj.isNull()))) {
|
||||||
throw damagedPDF(
|
throw damaged("Cross-reference stream does not have proper /W and /Index keys");
|
||||||
"xref stream",
|
|
||||||
xref_offset,
|
|
||||||
"Cross-reference stream does not have proper /W and /Index keys");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int W[3];
|
int W[3];
|
||||||
@ -989,16 +990,12 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
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).getIntValueAsInt();
|
||||||
if (W[i] > max_bytes) {
|
if (W[i] > max_bytes) {
|
||||||
throw damagedPDF(
|
throw damaged("Cross-reference stream's /W contains impossibly large values");
|
||||||
"xref stream",
|
|
||||||
xref_offset,
|
|
||||||
"Cross-reference stream's /W contains impossibly large values");
|
|
||||||
}
|
}
|
||||||
entry_size += toS(W[i]);
|
entry_size += toS(W[i]);
|
||||||
}
|
}
|
||||||
if (entry_size == 0) {
|
if (entry_size == 0) {
|
||||||
throw damagedPDF(
|
throw damaged("Cross-reference stream's /W indicates entry size of 0");
|
||||||
"xref stream", xref_offset, "Cross-reference stream's /W indicates entry size of 0");
|
|
||||||
}
|
}
|
||||||
unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size;
|
unsigned long long max_num_entries = static_cast<unsigned long long>(-1) / entry_size;
|
||||||
|
|
||||||
@ -1007,21 +1004,15 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
if (Index_obj.isArray()) {
|
if (Index_obj.isArray()) {
|
||||||
int n_index = Index_obj.getArrayNItems();
|
int n_index = Index_obj.getArrayNItems();
|
||||||
if ((n_index % 2) || (n_index < 2)) {
|
if ((n_index % 2) || (n_index < 2)) {
|
||||||
throw damagedPDF(
|
throw damaged("Cross-reference stream's /Index has an invalid number of values");
|
||||||
"xref stream",
|
|
||||||
xref_offset,
|
|
||||||
"Cross-reference stream's /Index has an invalid number of "
|
|
||||||
"values");
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < n_index; ++i) {
|
for (int i = 0; i < n_index; ++i) {
|
||||||
if (Index_obj.getArrayItem(i).isInteger()) {
|
if (Index_obj.getArrayItem(i).isInteger()) {
|
||||||
indx.push_back(Index_obj.getArrayItem(i).getIntValue());
|
indx.push_back(Index_obj.getArrayItem(i).getIntValue());
|
||||||
} else {
|
} else {
|
||||||
throw damagedPDF(
|
throw damaged(
|
||||||
"xref stream",
|
"Cross-reference stream's /Index's item " + std::to_string(i) +
|
||||||
xref_offset,
|
" is not an integer");
|
||||||
("Cross-reference stream's /Index's item " + std::to_string(i) +
|
|
||||||
" is not an integer"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
||||||
@ -1041,12 +1032,10 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
|||||||
// first object number + number of entries <= /Size. The spec requires us to ignore object
|
// first object number + number of entries <= /Size. The spec requires us to ignore object
|
||||||
// number > /Size.
|
// number > /Size.
|
||||||
if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) {
|
if (indx.at(i) > QIntC::to_longlong(max_num_entries - num_entries)) {
|
||||||
throw damagedPDF(
|
throw damaged(
|
||||||
"xref stream",
|
"Cross-reference stream claims to contain too many entries: " +
|
||||||
xref_offset,
|
std::to_string(indx.at(i)) + " " + std::to_string(max_num_entries) + " " +
|
||||||
("Cross-reference stream claims to contain too many entries: " +
|
std::to_string(num_entries));
|
||||||
std::to_string(indx.at(i)) + " " + std::to_string(max_num_entries) + " " +
|
|
||||||
std::to_string(num_entries)));
|
|
||||||
}
|
}
|
||||||
num_entries += toS(indx.at(i));
|
num_entries += toS(indx.at(i));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user