shithub: jbig2

Download patch

ref: 8033c8336691c0b833cde32d47f4bbf8d7f4d4f2
parent: a8ca8ed551e2897c422d0b6d46f1bd8ce30311b9
author: Shailesh Mistry <[email protected]>
date: Fri Jun 22 18:25:44 EDT 2012

Bug 693050 : Fix memory leak in 146f folder

--- a/jbig2_mmr.c
+++ b/jbig2_mmr.c
@@ -829,15 +829,13 @@
 	return result;
 }
 
-static void
+static int
 jbig2_decode_mmr_line(Jbig2MmrCtx *mmr, const byte *ref, byte *dst)
 {
-	int a0, a1, a2, b1, b2;
-	int c;
+	int a0 = -1;
+	int a1, a2, b1, b2;
+	int c = 0;		/* 0 is white, black is 1 */
 
-	a0 = -1;
-	c = 0;		/* 0 is white, black is 1 */
-
 	while (1)
 	{
 		uint32_t word = mmr->word;
@@ -862,6 +860,7 @@
 				a2 = a1 + black_run;
 				if (a1 > mmr->width) a1 = mmr->width;
 				if (a2 > mmr->width) a2 = mmr->width;
+				if (a2 < a1) return -1;
 				jbig2_set_bits(dst, a1, a2);
 				a0 = a2;
 				/* printf ("H %d %d\n", white_run, black_run); */
@@ -874,6 +873,7 @@
 				a2 = a1 + white_run;
 				if (a1 > mmr->width) a1 = mmr->width;
 				if (a2 > mmr->width) a2 = mmr->width;
+				if (a1 < a0) return -1;
 				jbig2_set_bits(dst, a0, a1);
 				a0 = a2;
 				/* printf ("H %d %d\n", black_run, white_run); */
@@ -886,7 +886,11 @@
 			jbig2_decode_mmr_consume(mmr, 4);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			b2 = jbig2_find_changing_element(ref, b1, mmr->width);
-			if (c) jbig2_set_bits(dst, a0, b2);
+			if (c)
+			{
+				if (b2 < a0) return -1;
+				jbig2_set_bits(dst, a0, b2);
+			}
 			a0 = b2;
 		}
 
@@ -895,7 +899,11 @@
 			/* printf ("V(0)\n"); */
 			jbig2_decode_mmr_consume(mmr, 1);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
-			if (c) jbig2_set_bits(dst, a0, b1);
+			if (c)
+			{
+				if (b1 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1);
+			}
 			a0 = b1;
 			c = !c;
 		}
@@ -906,7 +914,11 @@
 			jbig2_decode_mmr_consume(mmr, 3);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 + 1 > mmr->width) break;
-			if (c) jbig2_set_bits(dst, a0, b1 + 1);
+			if (c)
+			{
+				if (b1 + 1 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 + 1);
+			}
 			a0 = b1 + 1;
 			c = !c;
 		}
@@ -917,7 +929,11 @@
 			jbig2_decode_mmr_consume(mmr, 6);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 + 2 > mmr->width) break;
-			if (c) jbig2_set_bits(dst, a0, b1 + 2);
+			if (c)
+			{
+				if (b1 + 2 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 + 2);
+			}
 			a0 = b1 + 2;
 			c = !c;
 		}
@@ -928,7 +944,11 @@
 			jbig2_decode_mmr_consume(mmr, 7);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 + 3 > mmr->width) break;
-			if (c) jbig2_set_bits(dst, a0, b1 + 3);
+			if (c)
+			{
+				if (b1 + 3 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 + 3);
+			}
 			a0 = b1 + 3;
 			c = !c;
 		}
@@ -939,7 +959,11 @@
 			jbig2_decode_mmr_consume(mmr, 3);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 - 1 < 0) break;
-			if (c) jbig2_set_bits(dst, a0, b1 - 1);
+			if (c)
+			{
+				if (b1 - 1 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 - 1);
+			}
 			a0 = b1 - 1;
 			c = !c;
 		}
@@ -950,7 +974,11 @@
 			jbig2_decode_mmr_consume(mmr, 6);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 - 2 < 0) break;
-			if (c) jbig2_set_bits(dst, a0, b1 - 2);
+			if (c)
+			{
+				if (b1 - 2 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 - 2);
+			}
 			a0 = b1 - 2;
 			c = !c;
 		}
@@ -961,7 +989,11 @@
 			jbig2_decode_mmr_consume(mmr, 7);
 			b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
 			if (b1 - 3 < 0) break;
-			if (c) jbig2_set_bits(dst, a0, b1 - 3);
+			if (c)
+			{
+				if (b1 - 3 < a0) return -1;
+				jbig2_set_bits(dst, a0, b1 - 3);
+			}
 			a0 = b1 - 3;
 			c = !c;
 		}
@@ -969,6 +1001,8 @@
 		else
 			break;
 	}
+
+	return 0;
 }
 
 int
@@ -983,17 +1017,19 @@
 	byte *dst = image->data;
 	byte *ref = NULL;
 	int y;
+	int code = 0;
 
 	jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
 	for (y = 0; y < image->height; y++) {
 		memset(dst, 0, rowstride);
-		jbig2_decode_mmr_line(&mmr, ref, dst);
+		code = jbig2_decode_mmr_line(&mmr, ref, dst);
+		if (code < 0) return code;
 		ref = dst;
 		dst += rowstride;
 	}
 
-	return 0;
+	return code;
 }
 
 /**
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -695,6 +695,7 @@
 	  if (code) {
 	    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
 	      "error decoding MMR bitmap image!");
+	    jbig2_image_release(ctx, image);
 	    goto cleanup4;
 	  }
 	}