Fix infinite loop in JBIG2 decoder with >4 referred-to segments

Fixes issue #20439 where pdf.js would hang on JBIG2 images with more
than 4 referred-to segments.

The bug had two parts:
1. Checking the entire referredFlags byte (=== 7) instead of the
   extracted referredToCount value (top 3 bits)
2. Incorrect byte count calculation for retention flags, missing the
   +1 for the segment's own retention bit

According to the JBIG2 spec, retention flags need (referredToCount + 1)
bits total: 1 for the segment itself plus 1 for each referred segment.
The correct byte count is ceil((referredToCount + 1) / 8) which equals
(referredToCount + 8) >> 3.
This commit is contained in:
Gaurang Bhatia 2025-11-14 02:15:48 +05:30
parent e7288dca8e
commit b5c03c5bd4

View File

@ -1165,15 +1165,15 @@ function readSegmentHeader(data, start) {
let referredToCount = (referredFlags >> 5) & 7;
const retainBits = [referredFlags & 31];
let position = start + 6;
if (referredFlags === 7) {
if (referredToCount === 7) {
referredToCount = readUint32(data, position - 1) & 0x1fffffff;
position += 3;
let bytes = (referredToCount + 7) >> 3;
let bytes = (referredToCount + 8) >> 3;
retainBits[0] = data[position++];
while (--bytes > 0) {
retainBits.push(data[position++]);
}
} else if (referredFlags === 5 || referredFlags === 6) {
} else if (referredToCount === 5 || referredToCount === 6) {
throw new Jbig2Error("invalid referred-to flags");
}