mercurial/mpatch.c
changeset 4375 11dc22eb8e8d
parent 3138 cc856c4d91ca
child 4376 4759da3e4dc8
equal deleted inserted replaced
4367:3f1b0c0fb4fd 4375:11dc22eb8e8d
   219 /* decode a binary patch into a hunk list */
   219 /* decode a binary patch into a hunk list */
   220 static struct flist *decode(char *bin, int len)
   220 static struct flist *decode(char *bin, int len)
   221 {
   221 {
   222 	struct flist *l;
   222 	struct flist *l;
   223 	struct frag *lt;
   223 	struct frag *lt;
   224 	char *end = bin + len;
   224 	char *data = bin + 12, *end = bin + len;
   225 	char decode[12]; /* for dealing with alignment issues */
   225 	char decode[12]; /* for dealing with alignment issues */
   226 
   226 
   227 	/* assume worst case size, we won't have many of these lists */
   227 	/* assume worst case size, we won't have many of these lists */
   228 	l = lalloc(len / 12);
   228 	l = lalloc(len / 12);
   229 	if (!l)
   229 	if (!l)
   230 		return NULL;
   230 		return NULL;
   231 
   231 
   232 	lt = l->tail;
   232 	lt = l->tail;
   233 
   233 
   234 	while (bin < end) {
   234 	while (data <= end) {
   235 		memcpy(decode, bin, 12);
   235 		memcpy(decode, bin, 12);
   236 		lt->start = ntohl(*(uint32_t *)decode);
   236 		lt->start = ntohl(*(uint32_t *)decode);
   237 		lt->end = ntohl(*(uint32_t *)(decode + 4));
   237 		lt->end = ntohl(*(uint32_t *)(decode + 4));
   238 		lt->len = ntohl(*(uint32_t *)(decode + 8));
   238 		lt->len = ntohl(*(uint32_t *)(decode + 8));
   239 		lt->data = bin + 12;
   239 		if (lt->start > lt->end)
   240 		bin += 12 + lt->len;
   240 			break; /* sanity check */
       
   241 		bin = data + lt->len;
       
   242 		if (bin < data)
       
   243 			break; /* big data + big (bogus) len can wrap around */
       
   244 		lt->data = data;
       
   245 		data = bin + 12;
   241 		lt++;
   246 		lt++;
   242 	}
   247 	}
   243 
   248 
   244 	if (bin != end) {
   249 	if (bin != end) {
   245 		if (!PyErr_Occurred())
   250 		if (!PyErr_Occurred())
   365 static PyObject *
   370 static PyObject *
   366 patchedsize(PyObject *self, PyObject *args)
   371 patchedsize(PyObject *self, PyObject *args)
   367 {
   372 {
   368 	long orig, start, end, len, outlen = 0, last = 0;
   373 	long orig, start, end, len, outlen = 0, last = 0;
   369 	int patchlen;
   374 	int patchlen;
   370 	char *bin, *binend;
   375 	char *bin, *binend, *data;
   371 	char decode[12]; /* for dealing with alignment issues */
   376 	char decode[12]; /* for dealing with alignment issues */
   372 
   377 
   373 	if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
   378 	if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
   374 		return NULL;
   379 		return NULL;
   375 
   380 
   376 	binend = bin + patchlen;
   381 	binend = bin + patchlen;
   377 
   382 	data = bin + 12;
   378 	while (bin < binend) {
   383 
       
   384 	while (data <= binend) {
   379 		memcpy(decode, bin, 12);
   385 		memcpy(decode, bin, 12);
   380 		start = ntohl(*(uint32_t *)decode);
   386 		start = ntohl(*(uint32_t *)decode);
   381 		end = ntohl(*(uint32_t *)(decode + 4));
   387 		end = ntohl(*(uint32_t *)(decode + 4));
   382 		len = ntohl(*(uint32_t *)(decode + 8));
   388 		len = ntohl(*(uint32_t *)(decode + 8));
   383 		bin += 12 + len;
   389 		if (start > end)
       
   390 			break; /* sanity check */
       
   391 		bin = data + len;
       
   392 		if (bin < data)
       
   393 			break; /* big data + big (bogus) len can wrap around */
       
   394 		data = bin + 12;
   384 		outlen += start - last;
   395 		outlen += start - last;
   385 		last = end;
   396 		last = end;
   386 		outlen += len;
   397 		outlen += len;
   387 	}
   398 	}
   388 
   399