95 lines
3.2 KiB
Diff
95 lines
3.2 KiB
Diff
From dc6b8098b52db7e1a9b20c1ef6f1006555c04b1b Mon Sep 17 00:00:00 2001
|
|
From: Sebastian Rasmussen <sebras@gmail.com>
|
|
Date: Fri, 27 Mar 2020 05:41:07 +0800
|
|
Subject: [PATCH] jbig2dec: Adjust number of bytes consumed by MMR decoder.
|
|
|
|
The MMR decoder pre-buffers up to 32 bits of encoded input data in a word
|
|
buffer before they are consumed by the MMR decoder. Once bits are consumed, the
|
|
pre-buffer will be filled up with more input data. When filling up the buffer
|
|
the decoder would previously stay clear of reading data belonging to succeeding
|
|
segments, but still indicated that it consumed those bytes it never read. Once
|
|
finished the MMR decoder lied to the caller by propagating the incorrect number
|
|
of consumed bytes. The caller subtracted the consumed number of bytes from the
|
|
size and end up in underflow causing the next MMR decoding to first read input
|
|
data at the wrong location, later ending up attempting to read outside the MMR
|
|
encoded input buffer.
|
|
|
|
Now, the MMR decoder keeps track of how many bits it has consumed and
|
|
accurately rounds this number up to a whole number of bytes to the caller.
|
|
|
|
Fixes OSS-fuzz issue 17855.
|
|
|
|
Thanks to OSS-fuzz for reporting.
|
|
---
|
|
jbig2dec/jbig2_mmr.c | 27 ++++++++++++++++-----------
|
|
1 file changed, 16 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/jbig2dec/jbig2_mmr.c b/jbig2dec/jbig2_mmr.c
|
|
index 8029c81..94ff429 100644
|
|
--- a/jbig2dec/jbig2_mmr.c
|
|
+++ b/jbig2dec/jbig2_mmr.c
|
|
@@ -45,6 +45,7 @@ typedef struct {
|
|
uint32_t height;
|
|
const byte *data;
|
|
size_t size;
|
|
+ size_t consumed_bits;
|
|
uint32_t data_index;
|
|
uint32_t bit_index;
|
|
uint32_t word;
|
|
@@ -58,30 +59,34 @@ typedef struct {
|
|
static void
|
|
jbig2_decode_mmr_init(Jbig2MmrCtx *mmr, int width, int height, const byte *data, size_t size)
|
|
{
|
|
- size_t i;
|
|
- uint32_t word = 0;
|
|
-
|
|
mmr->width = width;
|
|
mmr->height = height;
|
|
mmr->data = data;
|
|
mmr->size = size;
|
|
mmr->data_index = 0;
|
|
- mmr->bit_index = 0;
|
|
+ mmr->bit_index = 32;
|
|
+ mmr->word = 0;
|
|
+ mmr->consumed_bits = 0;
|
|
|
|
- for (i = 0; i < size && i < 4; i++)
|
|
- word |= (data[i] << ((3 - i) << 3));
|
|
- mmr->word = word;
|
|
+ while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) {
|
|
+ mmr->bit_index -= 8;
|
|
+ mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index);
|
|
+ mmr->data_index++;
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
jbig2_decode_mmr_consume(Jbig2MmrCtx *mmr, int n_bits)
|
|
{
|
|
+ mmr->consumed_bits += n_bits;
|
|
+ if (mmr->consumed_bits > mmr->size * 8)
|
|
+ mmr->consumed_bits = mmr->size * 8;
|
|
+
|
|
mmr->word <<= n_bits;
|
|
mmr->bit_index += n_bits;
|
|
- while (mmr->bit_index >= 8) {
|
|
+ while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) {
|
|
mmr->bit_index -= 8;
|
|
- if (mmr->data_index + 4 < mmr->size)
|
|
- mmr->word |= (mmr->data[mmr->data_index + 4] << mmr->bit_index);
|
|
+ mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index);
|
|
mmr->data_index++;
|
|
}
|
|
}
|
|
@@ -1259,6 +1264,6 @@ jbig2_decode_halftone_mmr(Jbig2Ctx *ctx, const Jbig2GenericRegionParams *params,
|
|
jbig2_decode_mmr_consume(&mmr, 24);
|
|
}
|
|
|
|
- *consumed_bytes += mmr.data_index + (mmr.bit_index >> 3) + (mmr.bit_index > 0 ? 1 : 0);
|
|
+ *consumed_bytes += (mmr.consumed_bits + 7) / 8;
|
|
return code;
|
|
}
|
|
--
|
|
1.8.3.1
|
|
|