shithub: jbig2

Download patch

ref: 33e85ea71051ad64ca4bb8b874dcf8bed9b66e62
parent: 1d120cab65c74fe97e4e4512f6a034f0fba0cac5
author: Shailesh Mistry <shailesh.mistry@hotmail.co.uk>
date: Wed Jan 25 14:21:08 EST 2012

Bug 691254: This patch prevents the seg fault in Jbig2_042_14.pdf.

--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -237,6 +237,7 @@
   Jbig2WordStream *ws = NULL;
   Jbig2HuffmanState *hs = NULL;
   Jbig2HuffmanTable *SDHUFFRDX = NULL;
+  Jbig2HuffmanTable *SBHUFFRSIZE = NULL;
   Jbig2ArithState *as = NULL;
   Jbig2ArithIntCtx *IADH = NULL;
   Jbig2ArithIntCtx *IADW = NULL;
@@ -259,18 +260,25 @@
   if (ws == NULL)
   {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
-          "failed to allocate storage in jbig2_decode_symbol_dict");
+          "failed to allocate ws in jbig2_decode_symbol_dict");
       return NULL;
   }
 
+  as = jbig2_arith_new(ctx, ws);
+  if (as == NULL)
+  {
+      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+          "failed to allocate as in jbig2_decode_symbol_dict");
+      jbig2_word_stream_buf_free(ctx, ws);
+      return NULL;
+  }
+
   if (!params->SDHUFF) {
-      as = jbig2_arith_new(ctx, ws);
       IADH = jbig2_arith_int_ctx_new(ctx);
       IADW = jbig2_arith_int_ctx_new(ctx);
       IAEX = jbig2_arith_int_ctx_new(ctx);
       IAAI = jbig2_arith_int_ctx_new(ctx);
-      if ((as == NULL) || (IADH == NULL) || (IADW == NULL) ||
-          (IAEX == NULL) || (IAAI == NULL))
+      if ((IADH == NULL) || (IADW == NULL) || (IAEX == NULL) || (IAAI == NULL))
       {
           jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
               "failed to allocate storage for symbol bitmap");
@@ -294,7 +302,8 @@
           "huffman coded symbol dictionary");
       hs = jbig2_huffman_new(ctx, ws);
       SDHUFFRDX = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_O);
-      if ( (hs == NULL) || (SDHUFFRDX == NULL))
+      SBHUFFRSIZE = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_A);
+      if ( (hs == NULL) || (SDHUFFRDX == NULL) || (SBHUFFRSIZE == NULL))
       {
           jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
               "failed to allocate storage for symbol bitmap");
@@ -457,7 +466,6 @@
 		              jbig2_free(ctx->allocator, refagg_dicts);
 		              goto cleanup4;
 		          }
-		          refagg_dicts[0]->n_symbols = params->SDNUMINSYMS + params->SDNUMNEWSYMS;
 		          for (i=0;i < params->SDNUMINSYMS;i++)
 		          {
 			      refagg_dicts[0]->glyphs[i] = jbig2_image_clone(ctx, params->SDINSYMS->glyphs[i]);
@@ -467,8 +475,6 @@
 			  if (tparams == NULL) {
 			      code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
 			      "Out of memory creating text region params");
-			      jbig2_sd_release(ctx, refagg_dicts[0]);
-			      jbig2_free(ctx->allocator, refagg_dicts);
 			      goto cleanup4;
 			  }
               if (!params->SDHUFF) {
@@ -518,9 +524,6 @@
 		      if (image == NULL) {
                   code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                       "Out of memory creating symbol image");
-                  jbig2_free(ctx->allocator, tparams);
-                  jbig2_sd_release(ctx, refagg_dicts[0]);
-                  jbig2_free(ctx->allocator, refagg_dicts);
                   goto cleanup4;
 		      }
 
@@ -537,18 +540,32 @@
 		      Jbig2Image *image;
 		      uint32_t ID;
 		      int32_t RDX, RDY;
+		      int BMSIZE = 0;
 		      int ninsyms = params->SDINSYMS->n_symbols;
+		      int code1 = 0;
+		      int code2 = 0;
+		      int code3 = 0;
 
+		      /* 6.5.8.2.2 (2, 3, 4, 5) */
 		      if (params->SDHUFF) {
-			  ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
-			  RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code);
-			  RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code);
+		          ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
+		          RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code1);
+		          RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code2);
+		          BMSIZE = jbig2_huffman_get(hs, SBHUFFRSIZE, &code3);
+		          jbig2_huffman_skip(hs);
 		      } else {
-			  code = jbig2_arith_iaid_decode(IAID, as, (int32_t*)&ID);
-		          code = jbig2_arith_int_decode(IARDX, as, &RDX);
-		          code = jbig2_arith_int_decode(IARDY, as, &RDY);
+		          code1 = jbig2_arith_iaid_decode(IAID, as, (int32_t*)&ID);
+		          code2 = jbig2_arith_int_decode(IARDX, as, &RDX);
+		          code3 = jbig2_arith_int_decode(IARDY, as, &RDY);
 		      }
 
+		      if ((code1 < 0) || (code2 < 0) || (code3 < 0))
+		      {
+		          code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL,
+		              segment->number, "failed to decode data");
+		          goto cleanup4;
+		      }
+
 		      if (ID >= ninsyms+NSYMSDECODED) {
                   code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                       "refinement references unknown symbol %d", ID);
@@ -579,6 +596,12 @@
 		          &rparams, as, image, GR_stats);
 
 		      SDNEWSYMS->glyphs[NSYMSDECODED] = image;
+
+		      /* 6.5.8.2.2 (7) */
+		      if (params->SDHUFF) {
+		          if (BMSIZE == 0) BMSIZE = image->height * image->stride;
+		          jbig2_huffman_advance(hs, BMSIZE);
+		      }
 		  }
                }
 
@@ -779,7 +802,8 @@
   jbig2_sd_release(ctx, SDNEWSYMS);
   jbig2_free(ctx->allocator, SDNEWSYMWIDTHS);
   jbig2_release_huffman_table(ctx, SDHUFFRDX);
-  jbig2_free(ctx->allocator, hs);
+  jbig2_release_huffman_table(ctx, SBHUFFRSIZE);
+  jbig2_huffman_free(ctx, hs);
   jbig2_arith_iaid_ctx_free(ctx, IAID);
   jbig2_arith_int_ctx_free(ctx, IARDX);
   jbig2_arith_int_ctx_free(ctx, IARDY);
@@ -994,13 +1018,14 @@
     }
     if (params.SDINSYMS != NULL) {
       params.SDNUMINSYMS = params.SDINSYMS->n_symbols;
-    } else {
-     params.SDNUMINSYMS = 0;
     }
   }
 
-  /* 7.4.2.2 (4) */
-  if (!params.SDHUFF) {
+  /* 7.4.2.2 (3, 4) */
+  if (flags & 0x0100) {
+      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+        "segment marks bitmap coding context as used (NYI)");
+  } else {
       int stats_size = params.SDTEMPLATE == 0 ? 65536 :
           params.SDTEMPLATE == 1 ? 8192 : 1024;
       GB_stats = jbig2_new(ctx, Jbig2ArithCx, stats_size);
@@ -1025,10 +1050,6 @@
       }
   }
 
-  if (flags & 0x0100) {
-      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
-        "segment marks bitmap coding context as retained (NYI)");
-  }
 
   segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
 				  &params,
@@ -1039,6 +1060,15 @@
   if (segment->result) jbig2_dump_symbol_dict(ctx, segment);
 #endif
 
+  /* 7.4.2.2 (7) */
+  if (flags & 0x0200) {
+      /* todo: retain GB_stats, GR_stats */
+      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+          "segment marks bitmap coding context as retained (NYI)");
+  } else {
+      /* todo: free GB_stats, GR_stats */
+  }
+
 cleanup:
   if (params.SDHUFF) {
       jbig2_release_huffman_table(ctx, params.SDHUFFDH);
@@ -1046,8 +1076,6 @@
       jbig2_release_huffman_table(ctx, params.SDHUFFBMSIZE);
       jbig2_release_huffman_table(ctx, params.SDHUFFAGGINST);
   }
-
-  /* todo: retain or free GB_stats, GR_stats */
 
   return (segment->result != NULL) ? 0 : -1;
 
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -309,26 +309,32 @@
 		int32_t RDW, RDH, RDX, RDY;
 		Jbig2Image *refimage;
 		int BMSIZE = 0;
+		int code1 = 0;
+		int code2 = 0;
+		int code3 = 0;
+		int code4 = 0;
+		int code5 = 0;
 
 		/* 6.4.11 (1, 2, 3, 4) */
 		if (!params->SBHUFF) {
-		  int code1 = jbig2_arith_int_decode(params->IARDW, as, &RDW);
-		  int code2 = jbig2_arith_int_decode(params->IARDH, as, &RDH);
-		  int code3 = jbig2_arith_int_decode(params->IARDX, as, &RDX);
-		  int code4 = jbig2_arith_int_decode(params->IARDY, as, &RDY);
-          if ((code1 < 0) || (code2 < 0) || (code3 < 0) || (code4 < 0))
-          {
-              code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
-                  "failed to decode data");
-              goto cleanup2;
-          }
+		  code1 = jbig2_arith_int_decode(params->IARDW, as, &RDW);
+		  code2 = jbig2_arith_int_decode(params->IARDH, as, &RDH);
+		  code3 = jbig2_arith_int_decode(params->IARDX, as, &RDX);
+		  code4 = jbig2_arith_int_decode(params->IARDY, as, &RDY);
 		} else {
-		  RDW = jbig2_huffman_get(hs, params->SBHUFFRDW, &code);
-		  RDH = jbig2_huffman_get(hs, params->SBHUFFRDH, &code);
-		  RDX = jbig2_huffman_get(hs, params->SBHUFFRDX, &code);
-		  RDY = jbig2_huffman_get(hs, params->SBHUFFRDY, &code);
-		  BMSIZE = jbig2_huffman_get(hs, params->SBHUFFRSIZE, &code);
+		  RDW = jbig2_huffman_get(hs, params->SBHUFFRDW, &code1);
+		  RDH = jbig2_huffman_get(hs, params->SBHUFFRDH, &code2);
+		  RDX = jbig2_huffman_get(hs, params->SBHUFFRDX, &code3);
+		  RDY = jbig2_huffman_get(hs, params->SBHUFFRDY, &code4);
+		  BMSIZE = jbig2_huffman_get(hs, params->SBHUFFRSIZE, &code5);
 		  jbig2_huffman_skip(hs);
+		}
+
+		if ((code1 < 0) || (code2 < 0) || (code3 < 0) || (code4 < 0) || (code5 < 0))
+		{
+		    code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+		        "failed to decode data");
+		    goto cleanup2;
 		}
 
 		/* 6.4.11 (6) */