From b5c03c5bd4bea3441ccd3c7a0eb893d73adea46e Mon Sep 17 00:00:00 2001 From: Gaurang Bhatia Date: Fri, 14 Nov 2025 02:15:48 +0530 Subject: [PATCH] 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. --- src/core/jbig2.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/jbig2.js b/src/core/jbig2.js index df689d963..e31bd1f5e 100644 --- a/src/core/jbig2.js +++ b/src/core/jbig2.js @@ -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"); }