mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-31 03:17:22 +02:00
Move the ByteRange validation earlier when parsing signatures
Given that these checks are synchronous, we can avoid a little bit of unnecessary data-fetching if the `ByteRange` is invalid.
This commit is contained in:
parent
f38e8b659e
commit
1ce8e8a320
@ -2087,6 +2087,28 @@ class PDFDocument {
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
// Slice the two ByteRange byte spans out of the underlying PDF stream.
|
||||
// ByteRange = [a, b, c, d] means signed bytes are [a..a+b] and [c..c+d];
|
||||
// the gap covers the /Contents hex blob itself.
|
||||
const [a, b, c, d] = byteRange;
|
||||
// `/ByteRange` offsets are absolute, so compare against `stream.end`
|
||||
// (raw buffer end), not `stream.length` (post-`moveStart` payload).
|
||||
const fileLength = this.stream.end || 0;
|
||||
// Reject signatures whose /ByteRange is structurally implausible: it
|
||||
// must start at the file head, define a non-empty first span, leave
|
||||
// room for the /Contents blob between the two spans, and fit within
|
||||
// the file. Without this a crafted PDF can claim to cover the whole
|
||||
// document while only signing a small prologue.
|
||||
if (
|
||||
a !== 0 ||
|
||||
b <= 0 ||
|
||||
a + b > c ||
|
||||
c + d > fileLength ||
|
||||
fileLength === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const contents = await sigDict.getAsync("Contents");
|
||||
if (typeof contents !== "string" || contents.length === 0) {
|
||||
return null;
|
||||
@ -2106,29 +2128,6 @@ class PDFDocument {
|
||||
signatureType = 1;
|
||||
}
|
||||
|
||||
// Slice the two ByteRange byte spans out of the underlying PDF stream.
|
||||
// ByteRange = [a, b, c, d] means signed bytes are [a..a+b] and [c..c+d];
|
||||
// the gap covers the /Contents hex blob itself.
|
||||
const [a, b, c, d] = byteRange;
|
||||
const stream = this.stream;
|
||||
// `/ByteRange` offsets are absolute, so compare against `stream.end`
|
||||
// (raw buffer end), not `stream.length` (post-`moveStart` payload).
|
||||
const fileLength = stream.end || 0;
|
||||
// Reject signatures whose /ByteRange is structurally implausible: it
|
||||
// must start at the file head, define a non-empty first span, leave
|
||||
// room for the /Contents blob between the two spans, and fit within
|
||||
// the file. Without this a crafted PDF can claim to cover the whole
|
||||
// document while only signing a small prologue.
|
||||
if (
|
||||
a !== 0 ||
|
||||
b <= 0 ||
|
||||
a + b > c ||
|
||||
c + d > fileLength ||
|
||||
fileLength === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [t, name, reason, location, contactInfo, m] = await Promise.all([
|
||||
field.getAsync("T"),
|
||||
sigDict.getAsync("Name"),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user