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 */