mercurial/mpatch.c
changeset 4377 4759da3e4dc8
parent 4073 95ffa36d1d2a
parent 4358 11dc22eb8e8d
child 5444 a0952e4e52eb
--- a/mercurial/mpatch.c	Tue Apr 24 18:43:18 2007 -0700
+++ b/mercurial/mpatch.c	Wed Apr 25 18:43:55 2007 +0200
@@ -225,7 +225,7 @@
 {
 	struct flist *l;
 	struct frag *lt;
-	char *end = bin + len;
+	char *data = bin + 12, *end = bin + len;
 	char decode[12]; /* for dealing with alignment issues */
 
 	/* assume worst case size, we won't have many of these lists */
@@ -235,13 +235,18 @@
 
 	lt = l->tail;
 
-	while (bin < end) {
+	while (data <= end) {
 		memcpy(decode, bin, 12);
 		lt->start = ntohl(*(uint32_t *)decode);
 		lt->end = ntohl(*(uint32_t *)(decode + 4));
 		lt->len = ntohl(*(uint32_t *)(decode + 8));
-		lt->data = bin + 12;
-		bin += 12 + lt->len;
+		if (lt->start > lt->end)
+			break; /* sanity check */
+		bin = data + lt->len;
+		if (bin < data)
+			break; /* big data + big (bogus) len can wrap around */
+		lt->data = data;
+		data = bin + 12;
 		lt++;
 	}
 
@@ -371,20 +376,26 @@
 {
 	long orig, start, end, len, outlen = 0, last = 0;
 	int patchlen;
-	char *bin, *binend;
+	char *bin, *binend, *data;
 	char decode[12]; /* for dealing with alignment issues */
 
 	if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
 		return NULL;
 
 	binend = bin + patchlen;
+	data = bin + 12;
 
-	while (bin < binend) {
+	while (data <= binend) {
 		memcpy(decode, bin, 12);
 		start = ntohl(*(uint32_t *)decode);
 		end = ntohl(*(uint32_t *)(decode + 4));
 		len = ntohl(*(uint32_t *)(decode + 8));
-		bin += 12 + len;
+		if (start > end)
+			break; /* sanity check */
+		bin = data + len;
+		if (bin < data)
+			break; /* big data + big (bogus) len can wrap around */
+		data = bin + 12;
 		outlen += start - last;
 		last = end;
 		outlen += len;