This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pdfbox-jbig2.git
The following commit(s) were added to refs/heads/master by this push:
new b1223d8 PDFBOX-6162: decode to use local PREV state and enforce
explicit 9-bit context masking per JBIG2 spec
b1223d8 is described below
commit b1223d8a3d97f40c4d87259a0eeebe47c935c30f
Author: Maruan Sahyoun <[email protected]>
AuthorDate: Tue Apr 21 11:26:53 2026 +0200
PDFBOX-6162: decode to use local PREV state and enforce explicit 9-bit
context masking per JBIG2 spec
---
.../arithmetic/ArithmeticIntegerDecoder.java | 44 ++++++++++++----------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git
a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java
b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java
index 5ba42c3..725b668 100644
---
a/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java
+++
b/src/main/java/org/apache/pdfbox/jbig2/decoder/arithmetic/ArithmeticIntegerDecoder.java
@@ -27,8 +27,6 @@ public class ArithmeticIntegerDecoder
private final ArithmeticDecoder decoder;
- private int prev;
-
public ArithmeticIntegerDecoder(ArithmeticDecoder decoder)
{
this.decoder = decoder;
@@ -43,6 +41,13 @@ public class ArithmeticIntegerDecoder
*/
public long decode(CX cxIAx) throws IOException
{
+
+ // A.2.
+ // CX is identified by … the rightmost 9 bits of PREV
+ // ... Thus, PREV always contains the values of the eight
most-recently-decoded bits,
+ // plus a leading 1 bit, which is used to indicate the number of bits
decoded so far.
+ int prev = 1;
+
int v = 0;
int d, s;
@@ -54,39 +59,37 @@ public class ArithmeticIntegerDecoder
cxIAx = new CX(512, 1);
}
- prev = 1;
-
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
s = decoder.decode(cxIAx);
- setPrev(s);
+ prev = setPrev(prev, s);
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
if (d == 1)
{
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
if (d == 1)
{
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
if (d == 1)
{
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
if (d == 1)
{
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
if (d == 1)
{
@@ -125,9 +128,9 @@ public class ArithmeticIntegerDecoder
for (int i = 0; i < bitsToRead; i++)
{
- cxIAx.setIndex(prev);
+ cxIAx.setIndex(prev & 0x1FF);
d = decoder.decode(cxIAx);
- setPrev(d);
+ prev = setPrev(prev, d);
v = (v << 1) | d;
}
@@ -145,8 +148,8 @@ public class ArithmeticIntegerDecoder
return Long.MAX_VALUE;
}
- private void setPrev(int bit)
- {
+ private int setPrev(int prev, int bit)
+ {
if (prev < 256)
{
prev = ((prev << 1) | bit) & 0x1ff;
@@ -155,6 +158,7 @@ public class ArithmeticIntegerDecoder
{
prev = ((((prev << 1) | bit) & 511) | 256) & 0x1ff;
}
+ return prev;
}
/**