parrot/parrot — pull request #764 by rurban (2012-05-04 17:01:59+00:00)
Title: last found asan bug (I hope)

clang -faddress-sanitizer found this invalid read access in two scenarios:
1: cptr[8/8] with uint1
2: off-by-one access on multi-byte values

I checked with
if (bits > 1) {
/* cache last byte (for restoring hi bits) */
#if 0
Parrot_io_printf(interp,
"XXX structview unaligned: bits %d + elts[i].bit_offset %d = %d\n",
bits, elts[i].bit_offset, bits + elts[i].bit_offset );
#endif
tempc = cptr[(bits + elts[i].bit_offset - 1)/8];
}

and got unfixed:
ok 1 - 8 bits in one byte
ok 2 - single byte is byte-aligned
ok 3 - byte-aligned single byte is single byte when aligned
ok 4 - allocate an instance
XXX structview unaligned: bits 1 + elts[i].bit_offset 1 = 2
XXX structview unaligned: bits 1 + elts[i].bit_offset 3 = 4
XXX structview unaligned: bits 1 + elts[i].bit_offset 5 = 6
XXX structview unaligned: bits 1 + elts[i].bit_offset 7 = 8
=================================================================
==3014== ERROR: AddressSanitizer heap-buffer-overflow on address 0x7fbd42e5e481 at pc 0x7fbd47577a7b bp 0x7fffbb2a3830 sp 0x7fffbb2a3828
READ of size 1 at 0x7fbd42e5e481 thread T0

with bits >1 check only:
1..16
ok 1 - 8 bits in one byte
ok 2 - single byte is byte-aligned
ok 3 - byte-aligned single byte is single byte when aligned
ok 4 - allocate an instance
not ok 5 - bitpattern gives correct byte
# Have: 234
# Want: 170
XXX structview unaligned: bits 4 + elts[i].bit_offset 0 = 4
XXX structview unaligned: bits 8 + elts[i].bit_offset 4 = 12
XXX structview unaligned: bits 4 + elts[i].bit_offset 4 = 8
=================================================================
==3580== ERROR: AddressSanitizer heap-buffer-overflow on address 0x7fc0bfb62582 at pc 0x7fc0c4279beb bp 0x7fffada98690 sp 0x7fffada98688
READ of size 1 at 0x7fc0bfb62582 thread T0

fixed off-by-one also:
ok 5 - bitpattern gives correct byte
XXX structview unaligned: bits 4 + elts[i].bit_offset 0 = 4
XXX structview unaligned: bits 8 + elts[i].bit_offset 4 = 12
XXX structview unaligned: bits 4 + elts[i].bit_offset 4 = 8
...