shithub: jbig2

Download patch

ref: e69f9a2ac600685eeda9aa628d631e4eab8c86aa
parent: c9d7eeee85e5bad495a86f75eb926f5946693726
author: Sebastian Rasmussen <sebras@gmail.com>
date: Wed Mar 11 22:54:08 EDT 2020

jbig2dec: Fix signedness conversions.

--- a/jbig2.c
+++ b/jbig2.c
@@ -211,6 +211,22 @@
     return ((uint32_t) get_uint16(bptr) << 16) | get_uint16(bptr + 2);
 }
 
+static size_t
+jbig2_find_buffer_size(size_t desired)
+{
+    const size_t initial_buf_size = 1024;
+    size_t size = initial_buf_size;
+
+    if (desired == SIZE_MAX)
+        return SIZE_MAX;
+
+    while (size < desired)
+        size <<= 1;
+
+    return size;
+}
+
+
 /**
  * jbig2_data_in: submit data for decoding
  * @ctx: The jbig2dec decoder context
@@ -226,14 +242,8 @@
 int
 jbig2_data_in(Jbig2Ctx *ctx, const unsigned char *data, size_t size)
 {
-    const size_t initial_buf_size = 1024;
-
     if (ctx->buf == NULL) {
-        size_t buf_size = initial_buf_size;
-
-        do
-            buf_size <<= 1;
-        while (buf_size < size);
+        size_t buf_size = jbig2_find_buffer_size(size);
         ctx->buf = jbig2_new(ctx, byte, buf_size);
         if (ctx->buf == NULL) {
             return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate buffer when reading data");
@@ -241,21 +251,26 @@
         ctx->buf_size = buf_size;
         ctx->buf_rd_ix = 0;
         ctx->buf_wr_ix = 0;
-    } else if (ctx->buf_wr_ix + size > ctx->buf_size) {
-        if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) && ctx->buf_wr_ix - ctx->buf_rd_ix + size <= ctx->buf_size) {
-            memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix, ctx->buf_wr_ix - ctx->buf_rd_ix);
+    } else if (size > ctx->buf_size - ctx->buf_wr_ix) {
+        size_t already = ctx->buf_wr_ix - ctx->buf_rd_ix;
+
+        if (ctx->buf_rd_ix <= (ctx->buf_size >> 1) && size <= ctx->buf_size - already) {
+            memmove(ctx->buf, ctx->buf + ctx->buf_rd_ix, already);
         } else {
             byte *buf;
-            size_t buf_size = initial_buf_size;
+            size_t buf_size;
 
-            do
-                buf_size <<= 1;
-            while (buf_size < ctx->buf_wr_ix - ctx->buf_rd_ix + size);
+            if (already > SIZE_MAX - size) {
+                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "read data causes buffer to grow too large");
+            }
+
+            buf_size = jbig2_find_buffer_size(size + already);
+
             buf = jbig2_new(ctx, byte, buf_size);
             if (buf == NULL) {
                 return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to allocate bigger buffer when reading data");
             }
-            memcpy(buf, ctx->buf + ctx->buf_rd_ix, ctx->buf_wr_ix - ctx->buf_rd_ix);
+            memcpy(buf, ctx->buf + ctx->buf_rd_ix, already);
             jbig2_free(ctx->allocator, ctx->buf);
             ctx->buf = buf;
             ctx->buf_size = buf_size;
@@ -263,6 +278,7 @@
         ctx->buf_wr_ix -= ctx->buf_rd_ix;
         ctx->buf_rd_ix = 0;
     }
+
     memcpy(ctx->buf + ctx->buf_wr_ix, data, size);
     ctx->buf_wr_ix += size;
 
@@ -387,7 +403,7 @@
                 segment->rows = jbig2_get_uint32(p);
                 p += 4;
 
-                segment->data_length = p - s;
+                segment->data_length = (size_t) (p - s);
                 jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number, "unknown length determined to be %lu", (long) segment->data_length);
             }
             else if (segment->data_length > ctx->buf_wr_ix - ctx->buf_rd_ix)
@@ -483,15 +499,15 @@
     }
 
     if (offset < z->size) {
-        val |= z->data[offset] << 24;
+        val = (uint32_t) z->data[offset] << 24;
         ret++;
     }
     if (offset + 1 < z->size) {
-        val |= z->data[offset + 1] << 16;
+        val |= (uint32_t) z->data[offset + 1] << 16;
         ret++;
     }
     if (offset + 2 < z->size) {
-        val |= z->data[offset + 2] << 8;
+        val |= (uint32_t) z->data[offset + 2] << 8;
         ret++;
     }
     if (offset + 3 < z->size) {
--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -36,10 +36,10 @@
     int CT;
 
     uint32_t next_word;
-    int next_word_bytes;
+    size_t next_word_bytes;
 
     Jbig2WordStream *ws;
-    int offset;
+    size_t offset;
 };
 
 /*
@@ -94,10 +94,12 @@
 
         /* next_word_bytes can only be == 1 here, but let's be defensive. */
         if (as->next_word_bytes <= 1) {
-            as->next_word_bytes = as->ws->get_next_word(ctx, as->ws, as->offset, &as->next_word);
-            if (as->next_word_bytes < 0) {
+            int ret = as->ws->get_next_word(ctx, as->ws, as->offset, &as->next_word);
+            if (ret < 0) {
                 return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to check for marker code due to failure in underlying stream during arithmetic decoding");
             }
+
+            as->next_word_bytes = (size_t) ret;
             if (as->next_word_bytes == 0) {
                 jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to read end of possible terminating marker code, assuming terminating marker code");
                 as->next_word = 0xFF900000;
@@ -151,10 +153,12 @@
         as->next_word_bytes--;
 
         if (as->next_word_bytes == 0) {
-            as->next_word_bytes = as->ws->get_next_word(ctx, as->ws, as->offset, &as->next_word);
-            if (as->next_word_bytes < 0) {
+            int ret = as->ws->get_next_word(ctx, as->ws, as->offset, &as->next_word);
+            if (ret < 0) {
                 return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to read from underlying stream during arithmetic decoding");
             }
+            as->next_word_bytes = (size_t) ret;
+
             if (as->next_word_bytes == 0) {
                 jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to find terminating marker code before end of underlying stream, assuming terminating marker code");
                 as->next_word = 0xFF900000;
@@ -183,6 +187,7 @@
 jbig2_arith_new(Jbig2Ctx *ctx, Jbig2WordStream *ws)
 {
     Jbig2ArithState *result;
+    int ret;
 
     result = jbig2_new(ctx, Jbig2ArithState, 1);
     if (result == NULL) {
@@ -193,17 +198,20 @@
     result->ws = ws;
     result->offset = 0;
 
-    result->next_word_bytes = result->ws->get_next_word(ctx, result->ws, result->offset, &result->next_word);
-    if (result->next_word_bytes < 0) {
+    ret = result->ws->get_next_word(ctx, result->ws, result->offset, &result->next_word);
+    if (ret < 0) {
         jbig2_free(ctx->allocator, result);
         jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to initialize underlying stream of arithmetic decoder");
         return NULL;
     }
+
+    result->next_word_bytes = (size_t) ret;
     if (result->next_word_bytes == 0) {
         jbig2_free(ctx->allocator, result);
         jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to read first byte from underlying stream when initializing arithmetic decoder");
         return NULL;
     }
+
     result->offset += result->next_word_bytes;
 
     /* Figure F.1 */
--- a/jbig2_arith_iaid.c
+++ b/jbig2_arith_iaid.c
@@ -53,7 +53,7 @@
         return NULL;
     }
 
-    ctx_size = 1 << SBSYMCODELEN;
+    ctx_size = 1U << SBSYMCODELEN;
 
     result = jbig2_new(ctx, Jbig2ArithIaidCtx, 1);
     if (result == NULL) {
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -178,7 +178,7 @@
 int
 jbig2_huffman_skip(Jbig2HuffmanState *hs)
 {
-    int bits = hs->offset_bits & 7;
+    uint32_t bits = hs->offset_bits & 7;
     int code;
 
     if (bits) {
--- a/jbig2_priv.h
+++ b/jbig2_priv.h
@@ -86,8 +86,8 @@
 
     byte *buf;
     size_t buf_size;
-    unsigned int buf_rd_ix;
-    unsigned int buf_wr_ix;
+    size_t buf_rd_ix;
+    size_t buf_wr_ix;
 
     Jbig2FileState state;