shithub: jbig2

Download patch

ref: e0a50f1db9dc9adfe4b9001bed4c55a7dee56b31
parent: a9da05ed8eb0b63f6d6c378412f725100f9dd0fd
author: Shailesh Mistry <shailesh.mistry@hotmail.co.uk>
date: Sat May 25 23:01:24 EDT 2013

Bug 694021: Patch for seg fault related issues

The seg fault is due to the the image decoder trying to use an uninitialized
GR_stats. This also uncovered a few other errors that are covered here :-
1) GR_stats is now initialised in all places to prevent it reaching
   jbig2_arith_decode with fake values
2) jbig2_arith_decode has been updated to prevent access outside of the
   jbig2_arith_Qe array which now returns an error in such cases.
3) all uses of jbig2_decode_refinement_region now check for a returning error
   and act accordingly.

--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -229,6 +229,8 @@
   return result;
 }
 
+#define MAX_QE_ARRAY_SIZE 47
+
 /* could put bit fields in to minimize memory usage */
 typedef struct {
   unsigned short Qe;
@@ -236,7 +238,7 @@
   byte lps_xor; /* lps_xor = index ^ NLPS ^ (SWITCH << 7) */
 } Jbig2ArithQe;
 
-const Jbig2ArithQe jbig2_arith_Qe[] = {
+const Jbig2ArithQe jbig2_arith_Qe[MAX_QE_ARRAY_SIZE] = {
   { 0x5601,  1 ^  0,  1 ^  0 ^ 0x80 },
   { 0x3401,  2 ^  1,  6 ^  1 },
   { 0x1801,  3 ^  2,  9 ^  2 },
@@ -306,8 +308,18 @@
 jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx)
 {
   Jbig2ArithCx cx = *pcx;
-  const Jbig2ArithQe *pqe = &jbig2_arith_Qe[cx & 0x7f];
+  const Jbig2ArithQe *pqe;
+  unsigned int index = cx & 0x7f;
   bool D;
+
+  if (index >= MAX_QE_ARRAY_SIZE)
+  {
+	  return -1;
+  }
+  else
+  {
+	  pqe = &jbig2_arith_Qe[index];
+  }
 
   /* Figure E.15 */
   as->A -= pqe->Qe;
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -619,8 +619,9 @@
 		      rparams.DY = RDY;
 		      rparams.TPGRON = 0;
 		      memcpy(rparams.grat, params->sdrat, 4);
-		      jbig2_decode_refinement_region(ctx, segment,
+		      code = jbig2_decode_refinement_region(ctx, segment,
 		          &rparams, as, image, GR_stats);
+			  if (code < 0) goto cleanup4;
 
 		      SDNEWSYMS->glyphs[NSYMSDECODED] = image;
 
@@ -1094,20 +1095,18 @@
           goto cleanup;
       }
       memset(GB_stats, 0, stats_size);
-      if (params.SDREFAGG) {
-          stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
-          GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
-          if (GR_stats == NULL)
-          {
-              jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
-                  "failed to allocate GR_stats in jbig2_symbol_dictionary");
-              jbig2_free(ctx->allocator, GB_stats);
-              goto cleanup;
-          }
-          memset(GR_stats, 0, stats_size);
-      }
+	  
+	  stats_size = params.SDRTEMPLATE ? 1 << 10 : 1 << 13;
+	  GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
+	  if (GR_stats == NULL)
+	  {
+		  jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+			  "failed to allocate GR_stats in jbig2_symbol_dictionary");
+		  jbig2_free(ctx->allocator, GB_stats);
+		  goto cleanup;
+	  }
+	  memset(GR_stats, 0, stats_size);
   }
-
 
   segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
 				  &params,
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -379,8 +379,9 @@
 		rparams.DY = (RDH >> 1) + RDY;
 		rparams.TPGRON = 0;
 		memcpy(rparams.grat, params->sbrat, 4);
-		jbig2_decode_refinement_region(ctx, segment,
+		code = jbig2_decode_refinement_region(ctx, segment,
 		    &rparams, as, refimage, GR_stats);
+		if (code < 0) goto cleanup2;
 		IB = refimage;
 
 		jbig2_image_release(ctx, IBO);
@@ -834,7 +835,7 @@
     }
 
     /* 7.4.3.2 (3) */
-    if (!params.SBHUFF && params.SBREFINE) {
+    {
 	int stats_size = params.SBRTEMPLATE ? 1 << 10 : 1 << 13;
 	GR_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
     if (GR_stats == NULL)