ref: 7850aaff3651de4a4e7a6be1ac37f61bd9767055
parent: 3e6c1b0670740be3b138228dcc134bf5e6c1eceb
author: Math <mlafon@gmail.com>
date: Thu Feb 28 19:56:04 EST 2013
Bug 693507: check for out-of-bounds access Report error in get_next_word() functions on out-of-bounds access and handling of this error in both arithmetic and huffman decoders. When decoding a corrupted document, the arithmetic decoder can hit the end of the Jbig2 stream. The problem was that get_next_word() returned 0 in that case and that this lead to an infinite loop.
--- a/jbig2.c
+++ b/jbig2.c
@@ -438,8 +438,9 @@
size_t size;
} Jbig2WordStreamBuf;
-static uint32_t
-jbig2_word_stream_buf_get_next_word(Jbig2WordStream *self, int offset)
+static int
+jbig2_word_stream_buf_get_next_word(Jbig2WordStream *self, int offset,
+ uint32_t *word)
{
Jbig2WordStreamBuf *z = (Jbig2WordStreamBuf *)self;
const byte *data = z->data;
@@ -449,7 +450,7 @@
result = (data[offset] << 24) | (data[offset + 1] << 16) |
(data[offset + 2] << 8) | data[offset + 3];
else if (offset >= z->size)
- return 0;
+ return -1;
else
{
int i;
@@ -458,7 +459,8 @@
for (i = 0; i < z->size - offset; i++)
result |= data[offset + i] << ((3 - i) << 3);
}
- return result;
+ *word = result;
+ return 0;
}
Jbig2WordStream *
--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -41,6 +41,8 @@
Jbig2WordStream *ws;
int offset;
+
+ Jbig2Ctx *ctx;
};
#undef SOFTWARE_CONVENTION
@@ -59,7 +61,7 @@
*/
-static void
+static int
jbig2_arith_bytein (Jbig2ArithState *as)
{
byte B;
@@ -74,7 +76,12 @@
if (as->next_word_bytes == 1)
{
Jbig2WordStream *ws = as->ws;
- as->next_word = ws->get_next_word (ws, as->offset);
+ if (ws->get_next_word (ws, as->offset, &as->next_word))
+ {
+ jbig2_error(as->ctx, JBIG2_SEVERITY_FATAL, -1,
+ "end of jbig2 buffer reached at offset %d", as->offset);
+ return -1;
+ }
as->offset += 4;
B1 = (byte)((as->next_word >> 24) & 0xFF);
if (B1 > 0x8F)
@@ -145,7 +152,12 @@
{
Jbig2WordStream *ws = as->ws;
- as->next_word = ws->get_next_word (ws, as->offset);
+ if (ws->get_next_word (ws, as->offset, &as->next_word))
+ {
+ jbig2_error(as->ctx, JBIG2_SEVERITY_FATAL, -1,
+ "end of jbig2 buffer reached at offset %d", as->offset);
+ return -1;
+ }
as->offset += 4;
as->next_word_bytes = 4;
}
@@ -156,6 +168,7 @@
as->C += (B << 8);
#endif
}
+ return 0;
}
#if defined(JBIG2_DEBUG) || defined(JBIG2_DEBUG_ARITH)
@@ -185,8 +198,15 @@
}
result->ws = ws;
+ result->ctx = ctx;
- result->next_word = ws->get_next_word (ws, 0);
+ if (ws->get_next_word (ws, 0, &result->next_word))
+ {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "unable to get first word in jbig2_arith_new");
+ jbig2_free(ctx->allocator, result);
+ return NULL;
+ }
result->next_word_bytes = 4;
result->offset = 4;
@@ -197,7 +217,11 @@
result->C = (result->next_word >> 8) & 0xFF0000;
#endif
- jbig2_arith_bytein (result);
+ if (jbig2_arith_bytein (result))
+ {
+ jbig2_free(ctx->allocator, result);
+ return NULL;
+ }
result->C <<= 7;
result->CT -= 7;
result->A = 0x8000;
@@ -262,19 +286,20 @@
{ 0x5601, 46 ^ 46, 46 ^ 46 }
};
-static void
+static int
jbig2_arith_renormd (Jbig2ArithState *as)
{
/* Figure E.18 */
do
{
- if (as->CT == 0)
- jbig2_arith_bytein (as);
+ if ((as->CT == 0) && (jbig2_arith_bytein (as) < 0))
+ return -1;
as->A <<= 1;
as->C <<= 1;
as->CT--;
}
while ((as->A & 0x8000) == 0);
+ return 0;
}
bool
@@ -311,7 +336,8 @@
D = cx >> 7;
*pcx ^= pqe->mps_xor;
}
- jbig2_arith_renormd (as);
+ if (jbig2_arith_renormd (as))
+ return -1;
return D;
}
else
@@ -335,7 +361,8 @@
D = 1 - (cx >> 7);
*pcx ^= pqe->lps_xor;
}
- jbig2_arith_renormd (as);
+ if (jbig2_arith_renormd (as))
+ return -1;
return D;
}
}
@@ -342,8 +369,8 @@
#ifdef TEST
-static uint32_t
-test_get_word (Jbig2WordStream *self, int offset)
+static int
+test_get_word (Jbig2WordStream *self, int offset, uint32_t *word)
{
byte stream[] = {
0x84, 0xC7, 0x3B, 0xFC, 0xE1, 0xA1, 0x43, 0x04, 0x02, 0x20, 0x00, 0x00,
@@ -352,10 +379,10 @@
0x00, 0x00
};
if (offset >= sizeof(stream))
- return 0;
- else
- return (stream[offset] << 24) | (stream[offset + 1] << 16) |
- (stream[offset + 2] << 8) | stream[offset + 3];
+ return -1;
+ *word = (stream[offset] << 24) | (stream[offset + 1] << 16) |
+ (stream[offset + 2] << 8) | stream[offset + 3];
+ return 0;
}
int
--- a/jbig2_arith_iaid.c
+++ b/jbig2_arith_iaid.c
@@ -86,6 +86,8 @@
for (i = 0; i < SBSYMCODELEN; i++)
{
D = jbig2_arith_decode(as, &IAIDx[PREV]);
+ if (D < 0)
+ return -1;
#ifdef VERBOSE
fprintf(stderr, "IAID%x: D = %d\n", PREV, D);
#endif
--- a/jbig2_arith_int.c
+++ b/jbig2_arith_int.c
@@ -69,28 +69,40 @@
int i;
S = jbig2_arith_decode(as, &IAx[PREV]);
+ if (S < 0)
+ return -1;
PREV = (PREV << 1) | S;
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = (PREV << 1) | bit;
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = (PREV << 1) | bit;
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = (PREV << 1) | bit;
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = (PREV << 1) | bit;
if (bit)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = (PREV << 1) | bit;
if (bit)
@@ -132,6 +144,8 @@
for (i = 0; i < n_tail; i++)
{
bit = jbig2_arith_decode(as, &IAx[PREV]);
+ if (bit < 0)
+ return -1;
PREV = ((PREV << 1) & 511) | (PREV & 256) | bit;
V = (V << 1) | bit;
}
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -103,6 +103,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x7bf7) << 1) | bit |
((line_m1 >> (7 - x_minor)) & 0x10) |
@@ -159,6 +161,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6],
y + params->gbat[7]) << 15;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
}
@@ -217,6 +221,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0xefb) << 1) | bit |
((line_m1 >> (8 - x_minor)) & 0x8) |
@@ -285,6 +291,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1bd) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x4) |
@@ -353,6 +361,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1b9) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x8) |
@@ -416,6 +426,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x1f7) << 1) | bit |
((line_m1 >> (10 - x_minor)) & 0x010);
@@ -462,6 +474,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
}
@@ -498,7 +512,10 @@
for (y = 0; y < GBH; y++)
{
- LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25]);
+ bit = jbig2_arith_decode(as, &GB_stats[0x9B25]);
+ if (bit < 0)
+ return -1;
+ LTP ^= bit;
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
@@ -522,6 +539,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6],
y + params->gbat[7]) << 15;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
@@ -548,7 +567,10 @@
int LTP = 0;
for (y = 0; y < GBH; y++) {
- LTP ^= jbig2_arith_decode(as, &GB_stats[0x0795]);
+ bit = jbig2_arith_decode(as, &GB_stats[0x0795]);
+ if (bit < 0)
+ return -1;
+ LTP ^= bit;
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
@@ -566,6 +588,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x , y - 2) << 11;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 12;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
@@ -592,7 +616,10 @@
int LTP = 0;
for (y = 0; y < GBH; y++) {
- LTP ^= jbig2_arith_decode(as, &GB_stats[0xE5]);
+ bit = jbig2_arith_decode(as, &GB_stats[0xE5]);
+ if (bit < 0)
+ return -1;
+ LTP ^= bit;
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
@@ -607,6 +634,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x , y - 2) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
@@ -633,7 +662,10 @@
int LTP = 0;
for (y = 0; y < GBH; y++) {
- LTP ^= jbig2_arith_decode(as, &GB_stats[0x0195]);
+ bit = jbig2_arith_decode(as, &GB_stats[0x0195]);
+ if (bit < 0)
+ return -1;
+ LTP ^= bit;
if (!LTP) {
for (x = 0; x < GBW; x++) {
CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
@@ -648,6 +680,8 @@
CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
} else {
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -52,11 +52,25 @@
uint32_t next_word;
int offset_bits;
int offset;
+ int offset_limit;
Jbig2WordStream *ws;
+ Jbig2Ctx *ctx;
};
+static uint32_t
+huff_get_next_word(Jbig2HuffmanState *hs, int offset)
+{
+ uint32_t word = 0;
+ Jbig2WordStream *ws = hs->ws;
+ if ((ws->get_next_word (ws, offset, &word)) &&
+ ((hs->offset_limit == 0) || (offset < hs->offset_limit)))
+ hs->offset_limit = offset;
+ return word;
+}
+
+
/** Allocate and initialize a new huffman coding state
* the returned pointer can simply be freed; this does
* not affect the associated Jbig2WordStream.
@@ -71,9 +85,11 @@
if (result != NULL) {
result->offset = 0;
result->offset_bits = 0;
- result->this_word = ws->get_next_word (ws, 0);
- result->next_word = ws->get_next_word (ws, 4);
+ result->offset_limit = 0;
result->ws = ws;
+ result->ctx = ctx;
+ result->this_word = huff_get_next_word(result, 0);
+ result->next_word = huff_get_next_word(result, 4);
} else {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
"failed to allocate new huffman coding state");
@@ -168,10 +184,9 @@
}
if (hs->offset_bits >= 32) {
- Jbig2WordStream *ws = hs->ws;
hs->this_word = hs->next_word;
hs->offset += 4;
- hs->next_word = ws->get_next_word (ws, hs->offset + 4);
+ hs->next_word = huff_get_next_word(hs, hs->offset + 4);
hs->offset_bits -= 32;
if (hs->offset_bits) {
hs->this_word = (hs->this_word << hs->offset_bits) |
@@ -184,8 +199,6 @@
*/
void jbig2_huffman_advance(Jbig2HuffmanState *hs, int offset)
{
- Jbig2WordStream *ws = hs->ws;
-
hs->offset += offset & ~3;
hs->offset_bits += (offset & 3) << 3;
if (hs->offset_bits >= 32) {
@@ -192,8 +205,8 @@
hs->offset += 4;
hs->offset_bits -= 32;
}
- hs->this_word = ws->get_next_word (ws, hs->offset);
- hs->next_word = ws->get_next_word (ws, hs->offset + 4);
+ hs->this_word = huff_get_next_word(hs, hs->offset);
+ hs->next_word = huff_get_next_word(hs, hs->offset + 4);
if (hs->offset_bits > 0)
hs->this_word = (hs->this_word << hs->offset_bits) |
(hs->next_word >> (32 - hs->offset_bits));
@@ -212,11 +225,18 @@
* without decoding against a table
*/
int32_t
-jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits)
+jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits, int *err)
{
uint32_t this_word = hs->this_word;
int32_t result;
+ if (hs->offset_limit && hs->offset >= hs->offset_limit) {
+ jbig2_error(hs->ctx, JBIG2_SEVERITY_FATAL, -1,
+ "end of jbig2 buffer reached at offset %d", hs->offset);
+ *err = -1;
+ return -1;
+ }
+
result = this_word >> (32 - bits);
hs->offset_bits += bits;
if (hs->offset_bits >= 32) {
@@ -223,7 +243,7 @@
hs->offset += 4;
hs->offset_bits -= 32;
hs->this_word = hs->next_word;
- hs->next_word = hs->ws->get_next_word(hs->ws, hs->offset + 4);
+ hs->next_word = huff_get_next_word(hs, hs->offset + 4);
if (hs->offset_bits) {
hs->this_word = (hs->this_word << hs->offset_bits) |
(hs->next_word >> (32 - hs->offset_bits));
@@ -250,6 +270,14 @@
int RANGELEN;
int32_t result;
+ if (hs->offset_limit && hs->offset >= hs->offset_limit) {
+ jbig2_error(hs->ctx, JBIG2_SEVERITY_FATAL, -1,
+ "end of Jbig2WordStream reached at offset %d", hs->offset);
+ if (oob)
+ *oob = -1;
+ return -1;
+ }
+
for (;;)
{
int log_table_size = table->log_table_size;
@@ -270,10 +298,9 @@
offset_bits += PREFLEN;
if (offset_bits >= 32)
{
- Jbig2WordStream *ws = hs->ws;
this_word = next_word;
hs->offset += 4;
- next_word = ws->get_next_word (ws, hs->offset + 4);
+ next_word = huff_get_next_word(hs, hs->offset + 4);
offset_bits -= 32;
hs->next_word = next_word;
PREFLEN = offset_bits;
@@ -303,10 +330,9 @@
offset_bits += RANGELEN;
if (offset_bits >= 32)
{
- Jbig2WordStream *ws = hs->ws;
this_word = next_word;
hs->offset += 4;
- next_word = ws->get_next_word (ws, hs->offset + 4);
+ next_word = huff_get_next_word(hs, hs->offset + 4);
offset_bits -= 32;
hs->next_word = next_word;
RANGELEN = offset_bits;
@@ -681,17 +707,17 @@
const byte test_stream[] = { 0xe9, 0xcb, 0xf4, 0x00 };
const byte test_tabindex[] = { 4, 2, 2, 1 };
-static uint32_t
-test_get_word (Jbig2WordStream *self, int offset)
+static int
+test_get_word (Jbig2WordStream *self, int offset, uint32_t *word)
{
/* assume test_stream[] is at least 4 bytes */
if (offset+3 > sizeof(test_stream))
- return 0;
- else
- return ( (test_stream[offset] << 24) |
- (test_stream[offset+1] << 16) |
- (test_stream[offset+2] << 8) |
- (test_stream[offset+3]) );
+ return -1;
+ *word = ( (test_stream[offset] << 24) |
+ (test_stream[offset+1] << 16) |
+ (test_stream[offset+2] << 8) |
+ (test_stream[offset+3]) );
+ return 0;
}
int
@@ -1956,13 +1982,15 @@
test_huffmancodes_t *h;
} test_stream_t;
-static uint32_t
-test_get_word(Jbig2WordStream *self, int offset)
+static int
+test_get_word(Jbig2WordStream *self, int offset, uint32_t *word)
{
uint32_t val = 0;
test_stream_t *st = (test_stream_t *)self;
if (st != NULL) {
if (st->h != NULL) {
+ if (offset >= st->h->input_len)
+ return -1;
if (offset < st->h->input_len) {
val |= (st->h->input[offset] << 24);
}
@@ -1977,7 +2005,8 @@
}
}
}
- return val;
+ *word = val;
+ return 0;
}
int
--- a/jbig2_huffman.h
+++ b/jbig2_huffman.h
@@ -76,7 +76,7 @@
const Jbig2HuffmanTable *table, bool *oob);
int32_t
-jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits);
+jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits, int *err);
#ifdef JBIG2_DEBUG
void jbig2_dump_huffman_state(Jbig2HuffmanState *hs);
--- a/jbig2_priv.h
+++ b/jbig2_priv.h
@@ -184,7 +184,7 @@
typedef struct _Jbig2WordStream Jbig2WordStream;
struct _Jbig2WordStream {
- uint32_t (*get_next_word) (Jbig2WordStream *self, int offset);
+ int (*get_next_word) (Jbig2WordStream *self, int offset, uint32_t *word);
};
Jbig2WordStream *
--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -86,6 +86,8 @@
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+params->grat[2],
y-dy+params->grat[3]) << 12;
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
}
@@ -136,6 +138,8 @@
CONTEXT |= jbig2_image_get_pixel(ref, x-dx-1, y-dy+0) << 8;
CONTEXT |= jbig2_image_get_pixel(ref, x-dx+0, y-dy-1) << 9;
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
jbig2_image_set_pixel(image, x, y, bit);
}
}
@@ -215,6 +219,8 @@
bool bit;
bit = jbig2_arith_decode(as, &GR_stats[CONTEXT]);
+ if (bit < 0)
+ return -1;
result |= bit << (7 - x_minor);
CONTEXT = ((CONTEXT & 0x0d6) << 1) | bit |
((line_m1 >> (9 - x_minor)) & 0x002) |
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -564,10 +564,11 @@
int code1 = 0;
int code2 = 0;
int code3 = 0;
+ int code4 = 0;
/* 6.5.8.2.2 (2, 3, 4, 5) */
if (params->SDHUFF) {
- ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
+ ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN, &code4);
RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code1);
RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code2);
BMSIZE = jbig2_huffman_get(hs, SBHUFFRSIZE, &code3);
@@ -578,7 +579,7 @@
code3 = jbig2_arith_int_decode(IARDY, as, &RDY);
}
- if ((code1 < 0) || (code2 < 0) || (code3 < 0))
+ if ((code1 < 0) || (code2 < 0) || (code3 < 0) || (code4 < 0))
{
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL,
segment->number, "failed to decode data");
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -112,7 +112,9 @@
/* parse and build the runlength code huffman table */
for (index = 0; index < 35; index++) {
- runcodelengths[index].PREFLEN = jbig2_huffman_get_bits(hs, 4);
+ runcodelengths[index].PREFLEN = jbig2_huffman_get_bits(hs, 4, &code);
+ if (code < 0)
+ goto cleanup1;
runcodelengths[index].RANGELEN = 0;
runcodelengths[index].RANGELOW = index;
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
@@ -162,9 +164,12 @@
} else {
len = 0; /* code == 33 or 34 */
}
- if (code == 32) range = jbig2_huffman_get_bits(hs, 2) + 3;
- else if (code == 33) range = jbig2_huffman_get_bits(hs, 3) + 3;
- else if (code == 34) range = jbig2_huffman_get_bits(hs, 7) + 11;
+ err = 0;
+ if (code == 32) range = jbig2_huffman_get_bits(hs, 2, &err) + 3;
+ else if (code == 33) range = jbig2_huffman_get_bits(hs, 3, &err) + 3;
+ else if (code == 34) range = jbig2_huffman_get_bits(hs, 7, &err) + 11;
+ if (err < 0)
+ goto cleanup1;
}
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
" read runcode%d at index %d (length %d range %d)", code, index, len, range);
@@ -274,11 +279,11 @@
if (params->SBSTRIPS == 1) {
CURT = 0;
} else if (params->SBHUFF) {
- CURT = jbig2_huffman_get_bits(hs, params->LOGSBSTRIPS);
+ CURT = jbig2_huffman_get_bits(hs, params->LOGSBSTRIPS, &code);
} else {
code = jbig2_arith_int_decode(params->IAIT, as, &CURT);
- if (code < 0) goto cleanup2;
}
+ if (code < 0) goto cleanup2;
T = STRIPT + CURT;
/* (3b.iv) / 6.4.10 - decode the symbol id */
@@ -311,11 +316,11 @@
}
if (params->SBREFINE) {
if (params->SBHUFF) {
- RI = jbig2_huffman_get_bits(hs, 1);
+ RI = jbig2_huffman_get_bits(hs, 1, &code);
} else {
code = jbig2_arith_int_decode(params->IARI, as, &RI);
- if (code < 0) goto cleanup2;
}
+ if (code < 0) goto cleanup2;
} else {
RI = 0;
}