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