shithub: jbig2

Download patch

ref: 8d137a51d74937dd876137e1d63a8a29d30c6041
parent: 87a7b8711df890470be7d96428b29fbf9079bde4
author: Sebastian Rasmussen <sebras@gmail.com>
date: Tue Jul 31 15:32:00 EDT 2018

jbig2dec: Support up to 16 bit gray-scale image for halftoning.

Without this commit if jbig2dec is fed a fuzzed bitstream where
HBPP ends up larger than 8, jbig2dec will access bits outside of
each 8 bit sample in GSVALS.

HBPP is in Table 22 in 6.6.4 defined to be 32 bits unsigned. The
specification in C.2 limits GSBPP to 6 bits unsigned, a maximum
value of 63, i.e. a gray-scale image with 63 bits per sample.
According to table 23 in 6.6.5 HBPP is assigned to GSBPP, so any
value larger than 63 would be out of spec.

A non-fuzzed bitstream that has HBPP larger than 9 is yet to be
encountered. So for the time being use uint16_t the GSVALS and
limit HBPP to 16. If a file with HBPP larger than 16 is ever
encountered, the type and limit needs to be revisited.

--- a/jbig2_halftone.c
+++ b/jbig2_halftone.c
@@ -258,13 +258,13 @@
  * returns: array of gray-scale values with GSW x GSH width/height
  *          0 on failure
  **/
-static uint8_t **
+static uint16_t **
 jbig2_decode_gray_scale_image(Jbig2Ctx *ctx, Jbig2Segment *segment,
                               const byte *data, const size_t size,
                               bool GSMMR, uint32_t GSW, uint32_t GSH,
                               uint32_t GSBPP, bool GSUSESKIP, Jbig2Image *GSKIP, int GSTEMPLATE, Jbig2ArithCx *GB_stats)
 {
-    uint8_t **GSVALS = NULL;
+    uint16_t **GSVALS = NULL;
     size_t consumed_bytes = 0;
     uint32_t i, j, stride, x, y;
     int code;
@@ -357,13 +357,13 @@
     }
 
     /* allocate GSVALS */
-    GSVALS = jbig2_new(ctx, uint8_t *, GSW);
+    GSVALS = jbig2_new(ctx, uint16_t *, GSW);
     if (GSVALS == NULL) {
         jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate GSVALS: %d bytes", GSW);
         goto cleanup;
     }
     for (i = 0; i < GSW; ++i) {
-        GSVALS[i] = jbig2_new(ctx, uint8_t, GSH);
+        GSVALS[i] = jbig2_new(ctx, uint16_t, GSH);
         if (GSVALS[i] == NULL) {
             jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to allocate GSVALS: %d bytes", GSH * GSW);
             /* free already allocated */
@@ -454,13 +454,13 @@
 {
     uint32_t HBPP;
     uint32_t HNUMPATS;
-    uint8_t **GI = NULL;
+    uint16_t **GI = NULL;
     Jbig2Image *HSKIP = NULL;
     Jbig2PatternDict *HPATS;
     uint32_t i;
     int32_t mg, ng;
     int32_t x, y;
-    uint8_t gray_val;
+    uint16_t gray_val;
     int code = 0;
 
     /* We need the patterns used in this region, get them from the referred pattern dictionary */
@@ -497,6 +497,10 @@
     HNUMPATS = HPATS->n_patterns;
     HBPP = 0;
     while (HNUMPATS > (1U << ++HBPP));
+    if (HBPP > 16) {
+        code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "HBPP is larger than supported (%u)", HBPP);
+        goto cleanup;
+    }
 
     /* 6.6.5 point 4. decode gray-scale image as mentioned in annex C */
     GI = jbig2_decode_gray_scale_image(ctx, segment, data, size,