Mercurial > hg
comparison mercurial/mpatch.c @ 15033:2ef2d3a5cd2d stable
parsers: avoid pointer aliasing
Newer versions of GCC have aggressive pointer alias optimizations that
might get fooled by our pointer manipulations. These issues shouldn't
be encountered in practice because distutils compiles extensions with
-fno-strict-alias but the code was not valid according to the standard.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 10 Aug 2011 13:40:01 -0500 |
parents | a4e0908ce35b |
children | 8d821a173e4e |
comparison
equal
deleted
inserted
replaced
15032:eb87fbc6d702 | 15033:2ef2d3a5cd2d |
---|---|
236 static struct flist *decode(const char *bin, int len) | 236 static struct flist *decode(const char *bin, int len) |
237 { | 237 { |
238 struct flist *l; | 238 struct flist *l; |
239 struct frag *lt; | 239 struct frag *lt; |
240 const char *data = bin + 12, *end = bin + len; | 240 const char *data = bin + 12, *end = bin + len; |
241 char decode[12]; /* for dealing with alignment issues */ | 241 uint32_t decode[3]; /* for dealing with alignment issues */ |
242 | 242 |
243 /* assume worst case size, we won't have many of these lists */ | 243 /* assume worst case size, we won't have many of these lists */ |
244 l = lalloc(len / 12); | 244 l = lalloc(len / 12); |
245 if (!l) | 245 if (!l) |
246 return NULL; | 246 return NULL; |
247 | 247 |
248 lt = l->tail; | 248 lt = l->tail; |
249 | 249 |
250 while (data <= end) { | 250 while (data <= end) { |
251 memcpy(decode, bin, 12); | 251 memcpy(decode, bin, 12); |
252 lt->start = ntohl(*(uint32_t *)decode); | 252 lt->start = ntohl(decode[0]); |
253 lt->end = ntohl(*(uint32_t *)(decode + 4)); | 253 lt->end = ntohl(decode[1]); |
254 lt->len = ntohl(*(uint32_t *)(decode + 8)); | 254 lt->len = ntohl(decode[2]); |
255 if (lt->start > lt->end) | 255 if (lt->start > lt->end) |
256 break; /* sanity check */ | 256 break; /* sanity check */ |
257 bin = data + lt->len; | 257 bin = data + lt->len; |
258 if (bin < data) | 258 if (bin < data) |
259 break; /* big data + big (bogus) len can wrap around */ | 259 break; /* big data + big (bogus) len can wrap around */ |
395 patchedsize(PyObject *self, PyObject *args) | 395 patchedsize(PyObject *self, PyObject *args) |
396 { | 396 { |
397 long orig, start, end, len, outlen = 0, last = 0; | 397 long orig, start, end, len, outlen = 0, last = 0; |
398 int patchlen; | 398 int patchlen; |
399 char *bin, *binend, *data; | 399 char *bin, *binend, *data; |
400 char decode[12]; /* for dealing with alignment issues */ | 400 uint32_t decode[3]; /* for dealing with alignment issues */ |
401 | 401 |
402 if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen)) | 402 if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen)) |
403 return NULL; | 403 return NULL; |
404 | 404 |
405 binend = bin + patchlen; | 405 binend = bin + patchlen; |
406 data = bin + 12; | 406 data = bin + 12; |
407 | 407 |
408 while (data <= binend) { | 408 while (data <= binend) { |
409 memcpy(decode, bin, 12); | 409 memcpy(decode, bin, 12); |
410 start = ntohl(*(uint32_t *)decode); | 410 start = ntohl(decode[0]); |
411 end = ntohl(*(uint32_t *)(decode + 4)); | 411 end = ntohl(decode[1]); |
412 len = ntohl(*(uint32_t *)(decode + 8)); | 412 len = ntohl(decode[2]); |
413 if (start > end) | 413 if (start > end) |
414 break; /* sanity check */ | 414 break; /* sanity check */ |
415 bin = data + len; | 415 bin = data + len; |
416 if (bin < data) | 416 if (bin < data) |
417 break; /* big data + big (bogus) len can wrap around */ | 417 break; /* big data + big (bogus) len can wrap around */ |