parsers.c: fix integer overflows
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Sun, 19 Oct 2008 20:16:37 +0200
changeset 7174 4da87407b845
parent 7168 834b8d7bd597
child 7175 5d8626b2c1db
parsers.c: fix integer overflows thanks to zzuf for helping finding those
mercurial/parsers.c
--- a/mercurial/parsers.c	Sun Oct 19 16:11:23 2008 +0200
+++ b/mercurial/parsers.c	Sun Oct 19 20:16:37 2008 +0200
@@ -164,7 +164,8 @@
 	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
 	char *str, *cur, *end, *cpos;
-	int state, mode, size, mtime, flen;
+	int state, mode, size, mtime;
+	unsigned int flen;
 	int len;
 	char decode[16]; /* for alignment */
 
@@ -195,8 +196,10 @@
 		mtime = ntohl(*(uint32_t *)(decode + 8));
 		flen = ntohl(*(uint32_t *)(decode + 12));
 		cur += 17;
-		if (cur + flen > end)
+		if (flen > end - cur) {
+			PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
 			goto quit;
+		}
 
 		entry = Py_BuildValue("ciii", state, mode, size, mtime);
 		PyObject_GC_UnTrack(entry); /* don't waste time with this */
@@ -294,6 +297,8 @@
 	const char *end = data + size;
 
 	while (data < end) {
+		unsigned int step;
+
                 offset_flags = ntohl(*((uint32_t *) (data + 4)));
                 if (n == 0) /* mask out version number for the first entry */
                         offset_flags &= 0xFFFF;
@@ -325,10 +330,13 @@
 		} else
 			PyList_SET_ITEM(index, n, entry); /* steals reference */
 
-		data += 64 + (inlined ? comp_len : 0);
 		n++;
+		step = 64 + (inlined ? comp_len : 0);
+		if (end - data < step)
+			break;
+		data += step;
 	}
-	if (data > end) {
+	if (data != end) {
 		if (!PyErr_Occurred())
 			PyErr_SetString(PyExc_ValueError, "corrupt index file");
 		return 0;