# HG changeset patch # User Thomas Arendsen Hein # Date 1177519435 -7200 # Node ID 4759da3e4dc8e3fd4ae35c7e4e9f94225fa86e85 # Parent de612b5f8d598a91fe3115a8971a4a8c16ab4d0c# Parent 11dc22eb8e8d01df171cc30cd566c30c9ed1a95f merge with stable diff --git a/mercurial/mpatch.c b/mercurial/mpatch.c --- a/mercurial/mpatch.c +++ b/mercurial/mpatch.c @@ -225,7 +225,7 @@ static struct flist *decode(char *bin, i { 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 @@ static struct flist *decode(char *bin, i 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 @@ patchedsize(PyObject *self, PyObject *ar { 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;