shithub: jbig2

Download patch

ref: 4886f1c69e712a730399da308bfb1b731a652cbb
parent: a27094d1833bf10c9ab3b612182aa23f4eb3044f
author: Shailesh Mistry <shailesh.mistry@hotmail.co.uk>
date: Mon May 14 14:08:00 EDT 2012

Bug 693025: Updated patch from Zeniko to fix various crashes and leaks

--- a/jbig2_halftone.c
+++ b/jbig2_halftone.c
@@ -142,7 +142,7 @@
   rparams.GBTEMPLATE = params->HDTEMPLATE;
   rparams.TPGDON = 0;	/* not used if HDMMR = 1 */
   rparams.USESKIP = 0;
-  rparams.gbat[0] = -params->HDPW;
+  rparams.gbat[0] = -(int8_t)params->HDPW;
   rparams.gbat[1] = 0;
   rparams.gbat[2] = -3;
   rparams.gbat[3] = -1;
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -253,6 +253,12 @@
       entry = &table->entries[this_word >> (32 - log_table_size)];
       flags = entry->flags;
       PREFLEN = entry->PREFLEN;
+      if ((flags == (byte)-1) && (PREFLEN == (int)-1) && (entry->u.RANGELOW == -1))
+      {
+          if (oob)
+              *oob = -1;
+          return -1;
+      }
 
       next_word = hs->next_word;
       offset_bits += PREFLEN;
@@ -386,6 +392,8 @@
         "couldn't allocate entries storage in jbig2_build_huffman_table");
     return NULL;
   }
+  /* fill now to catch missing JBIG2Globals later */
+  memset(entries, 0xFF, sizeof(Jbig2HuffmanEntry)*max_j);
   result->entries = entries;
 
   LENCOUNT[0] = 0;
--- a/jbig2_image.c
+++ b/jbig2_image.c
@@ -229,6 +229,9 @@
 #endif
 
     leftbyte = x >> 3;
+    if (leftbyte > dst->height * dst->stride)
+        return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+            "preventing heap overflow in jbig2_image_compose");
     rightbyte = (x + w - 1) >> 3;
     shift = x & 7;
 
--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -435,6 +435,7 @@
   Jbig2RegionSegmentInfo rsi;
   int offset = 0;
   byte seg_flags;
+  int code = 0;
 
   /* 7.4.7 */
   if (segment->data_length < 18)
@@ -509,12 +510,14 @@
     Jbig2ArithCx *GR_stats = NULL;
     int stats_size;
     Jbig2Image *image = NULL;
-    int code;
 
     image = jbig2_image_new(ctx, rsi.width, rsi.height);
     if (image == NULL)
-      return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
-               "unable to allocate refinement image");
+    {
+        code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+            "unable to allocate refinement image");
+        goto cleanup;
+    }
     jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
       "allocated %d x %d image buffer for region decode results",
           rsi.width, rsi.height);
@@ -523,7 +526,7 @@
     GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
     if (GR_stats == NULL)
     {
-        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+        code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
             "failed to allocate GR-stats in jbig2_refinement_region");
         goto cleanup;
     }
@@ -533,7 +536,7 @@
            segment->data_length - offset);
     if (ws == NULL)
     {
-        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+        code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
             "failed to allocate ws in jbig2_refinement_region");
         goto cleanup;
     }
@@ -541,7 +544,7 @@
     as = jbig2_arith_new(ctx, ws);
     if (as == NULL)
     {
-        jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+        code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
             "failed to allocate as in jbig2_refinement_region");
         goto cleanup;
     }
@@ -551,7 +554,7 @@
 
     if ((segment->flags & 63) == 40) {
         /* intermediate region. save the result for later */
-	segment->result = image;
+        segment->result = jbig2_image_clone(ctx, image);
     } else {
 	/* immediate region. composite onto the page */
         jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
@@ -559,14 +562,15 @@
             rsi.width, rsi.height, rsi.x, rsi.y);
 	jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page],
           image, rsi.x, rsi.y, rsi.op);
-        jbig2_image_release(ctx, image);
     }
 
 cleanup:
+    jbig2_image_release(ctx, image);
+    jbig2_image_release(ctx, params.reference);
     jbig2_free(ctx->allocator, as);
     jbig2_word_stream_buf_free(ctx, ws);
     jbig2_free(ctx->allocator, GR_stats);
   }
 
-  return 0;
+  return code;
 }
--- a/jbig2_segment.c
+++ b/jbig2_segment.c
@@ -25,6 +25,8 @@
 #include "jbig2_huffman.h"
 #include "jbig2_symbol_dict.h"
 #include "jbig2_metadata.h"
+#include "jbig2_arith.h"
+#include "jbig2_halftone.h"
 
 Jbig2Segment *
 jbig2_parse_segment_header (Jbig2Ctx *ctx, uint8_t *buf, size_t buf_size,
@@ -156,6 +158,10 @@
 	  if (segment->result != NULL)
 	    jbig2_image_release(ctx, (Jbig2Image*)segment->result);
 	  break;
+       case 16: /* pattern dictionary */
+      if (segment->result != NULL)
+        jbig2_hd_release(ctx, (Jbig2PatternDict*)segment->result);
+      break;
 	case 53: /* user-supplied huffman table */
 	  if (segment->result != NULL)
 		jbig2_table_free(ctx, (Jbig2HuffmanParams*)segment->result);
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -1068,6 +1068,7 @@
   } else {
       /* todo: free GB_stats, GR_stats */
   }
+  jbig2_free(ctx->allocator, GR_stats);
 
 cleanup:
   if (params.SDHUFF) {
@@ -1076,6 +1077,7 @@
       jbig2_release_huffman_table(ctx, params.SDHUFFBMSIZE);
       jbig2_release_huffman_table(ctx, params.SDHUFFAGGINST);
   }
+  jbig2_sd_release(ctx, params.SDINSYMS);
 
   return (segment->result != NULL) ? 0 : -1;
 
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -280,8 +280,9 @@
         if (code < 0) goto cleanup2;
 	    }
 	    if (ID >= SBNUMSYMS) {
-		return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
-                    "symbol id out of range! (%d/%d)", ID, SBNUMSYMS);
+            code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+                "symbol id out of range! (%d/%d)", ID, SBNUMSYMS);
+            goto cleanup2;
 	    }
 
 	    /* (3c.v) / 6.4.11 - look up the symbol bitmap IB */
@@ -836,7 +837,6 @@
     {
         code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
             "couldn't allocate text region image");
-        jbig2_image_release(ctx, image);
         goto cleanup2;
     }
     if (!params.SBHUFF) {
@@ -885,13 +885,12 @@
     {
         jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
             "failed to decode text region image data");
-        jbig2_image_release(ctx, image);
         goto cleanup4;
     }
 
     if ((segment->flags & 63) == 4) {
         /* we have an intermediate region here. save it for later */
-        segment->result = image;
+        segment->result = jbig2_image_clone(ctx, image);
     } else {
         /* otherwise composite onto the page */
         jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
@@ -899,7 +898,6 @@
             region_info.width, region_info.height, region_info.x, region_info.y);
         jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page], image,
             region_info.x, region_info.y, region_info.op);
-        jbig2_image_release(ctx, image);
     }
 
 cleanup4:
@@ -926,6 +924,7 @@
     if (!params.SBHUFF && params.SBREFINE) {
         jbig2_free(ctx->allocator, GR_stats);
     }
+    jbig2_image_release(ctx, image);
 
 cleanup1:
     if (params.SBHUFF) {