ur: fixes buffer over-read bugs in bitstream in tests

This commit is contained in:
Joe Bryan 2020-08-28 14:45:51 -07:00
parent 1ea8e73104
commit 7b42f540b4
2 changed files with 121 additions and 85 deletions

View File

@ -1126,13 +1126,15 @@ _test_bsr64(void)
static void static void
_bsr_bytes_any_slow(ur_bsr_t *bsr, uint64_t len, uint8_t *out) _bsr_bytes_any_slow(ur_bsr_t *bsr, uint64_t len, uint8_t *out)
{ {
uint64_t i, len_byt = len >> 3; uint64_t i, len_byt = len >> 3, len_bit = ur_mask_3(len);
for ( i = 0; i < len_byt; i++ ) { for ( i = 0; i < len_byt; i++ ) {
out[i] = _bsr8_any_slow(bsr, 8); out[i] = _bsr8_any_slow(bsr, 8);
} }
out[len_byt] = _bsr8_any_slow(bsr, ur_mask_3(len)); if ( len_bit ) {
out[len_byt] = _bsr8_any_slow(bsr, len_bit);
}
} }
static int static int

View File

@ -130,22 +130,22 @@ ur_bsr32_any(ur_bsr_t *bsr, uint8_t len)
return 0; return 0;
} }
else { else {
uint8_t off = bsr->off; uint8_t off = bsr->off;
uint8_t rest = 8 - off; uint8_t rest = 8 - off;
const uint8_t *b = bsr->bytes; uint32_t m = bsr->bytes[0] >> off;
uint32_t m = b[0] >> off;
if ( len < rest ) { if ( len < rest ) {
bsr->off = off + len; bsr->off = off + len;
return m & ((1 << len) - 1); return m & ((1 << len) - 1);
} }
else { else {
uint8_t mask, len_byt; const uint8_t *b;
uint32_t l; uint8_t mask, len_byt;
uint32_t l;
len -= rest; len -= rest;
left--; left--;
bsr->bytes++; b = ++bsr->bytes;
len_byt = len >> 3; len_byt = len >> 3;
@ -164,33 +164,44 @@ ur_bsr32_any(ur_bsr_t *bsr, uint8_t len)
mask = (1 << off) - 1; mask = (1 << off) - 1;
switch ( len_byt ) { switch ( len_byt ) {
default: assert(0);
case 4: { case 4: {
l = (uint32_t)b[1] l = (uint32_t)b[0]
^ (uint32_t)b[2] << 8 ^ (uint32_t)b[1] << 8
^ (uint32_t)b[3] << 16 ^ (uint32_t)b[2] << 16
^ (uint32_t)b[4] << 24; ^ (uint32_t)b[3] << 24;
} break; } break;
case 3: { case 3: {
l = (uint32_t)b[1] l = (uint32_t)b[0]
^ (uint32_t)b[2] << 8 ^ (uint32_t)b[1] << 8
^ (uint32_t)b[3] << 16 ^ (uint32_t)b[2] << 16;
^ (uint32_t)(b[4] & mask) << 24;
if ( mask ) {
l ^= (uint32_t)(b[3] & mask) << 24;
}
} break; } break;
case 2: { case 2: {
l = (uint32_t)b[1] l = (uint32_t)b[0]
^ (uint32_t)b[2] << 8 ^ (uint32_t)b[1] << 8;
^ (uint32_t)(b[3] & mask) << 16;
if ( mask ) {
l ^= (uint32_t)(b[2] & mask) << 16;
}
} break; } break;
case 1: { case 1: {
l = (uint32_t)b[1] l = (uint32_t)b[0];
^ (uint32_t)(b[2] & mask) << 8;
if ( mask ) {
l ^= (uint32_t)(b[1] & mask) << 8;
}
} break; } break;
case 0: { case 0: {
l = (uint32_t)(b[1] & mask); l = ( mask ) ? (uint32_t)(b[0] & mask) : 0;
} break; } break;
} }
@ -212,22 +223,22 @@ ur_bsr64_any(ur_bsr_t *bsr, uint8_t len)
return 0; return 0;
} }
else { else {
uint8_t off = bsr->off; uint8_t off = bsr->off;
uint8_t rest = 8 - off; uint8_t rest = 8 - off;
const uint8_t *b = bsr->bytes; uint64_t m = bsr->bytes[0] >> off;
uint64_t m = b[0] >> off;
if ( len < rest ) { if ( len < rest ) {
bsr->off = off + len; bsr->off = off + len;
return m & ((1 << len) - 1); return m & ((1 << len) - 1);
} }
else { else {
uint8_t mask, len_byt; const uint8_t *b;
uint64_t l; uint8_t mask, len_byt;
uint64_t l;
len -= rest; len -= rest;
left--; left--;
bsr->bytes++; b = ++bsr->bytes;
len_byt = len >> 3; len_byt = len >> 3;
@ -247,74 +258,95 @@ ur_bsr64_any(ur_bsr_t *bsr, uint8_t len)
switch ( len_byt ) { switch ( len_byt ) {
case 8: { case 8: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16
^ (uint64_t)b[4] << 24 ^ (uint64_t)b[3] << 24
^ (uint64_t)b[5] << 32 ^ (uint64_t)b[4] << 32
^ (uint64_t)b[6] << 40 ^ (uint64_t)b[5] << 40
^ (uint64_t)b[7] << 48 ^ (uint64_t)b[6] << 48
^ (uint64_t)b[8] << 56; ^ (uint64_t)b[7] << 56;
} break; } break;
case 7: { case 7: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16
^ (uint64_t)b[4] << 24 ^ (uint64_t)b[3] << 24
^ (uint64_t)b[5] << 32 ^ (uint64_t)b[4] << 32
^ (uint64_t)b[6] << 40 ^ (uint64_t)b[5] << 40
^ (uint64_t)b[7] << 48 ^ (uint64_t)b[6] << 48;
^ (uint64_t)(b[8] & mask) << 56;
if ( mask ) {
l ^= (uint64_t)(b[7] & mask) << 56;
}
} break; } break;
case 6: { case 6: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16
^ (uint64_t)b[4] << 24 ^ (uint64_t)b[3] << 24
^ (uint64_t)b[5] << 32 ^ (uint64_t)b[4] << 32
^ (uint64_t)b[6] << 40 ^ (uint64_t)b[5] << 40;
^ (uint64_t)(b[7] & mask) << 48;
if ( mask ) {
l ^= (uint64_t)(b[6] & mask) << 48;
}
} break; } break;
case 5: { case 5: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16
^ (uint64_t)b[4] << 24 ^ (uint64_t)b[3] << 24
^ (uint64_t)b[5] << 32 ^ (uint64_t)b[4] << 32;
^ (uint64_t)(b[6] & mask) << 40;
if ( mask ) {
l ^= (uint64_t)(b[5] & mask) << 40;
}
} break; } break;
case 4: { case 4: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16
^ (uint64_t)b[4] << 24 ^ (uint64_t)b[3] << 24;
^ (uint64_t)(b[5] & mask) << 32;
if ( mask ) {
l ^= (uint64_t)(b[4] & mask) << 32;
}
} break; } break;
case 3: { case 3: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8
^ (uint64_t)b[3] << 16 ^ (uint64_t)b[2] << 16;
^ (uint64_t)(b[4] & mask) << 24;
if ( mask ) {
l ^= (uint64_t)(b[3] & mask) << 24;
}
} break; } break;
case 2: { case 2: {
l = (uint64_t)b[1] l = (uint64_t)b[0]
^ (uint64_t)b[2] << 8 ^ (uint64_t)b[1] << 8;
^ (uint64_t)(b[3] & mask) << 16;
if ( mask ) {
l ^= (uint64_t)(b[2] & mask) << 16;
}
} break; } break;
case 1: { case 1: {
l = (uint64_t)b[1] l = (uint64_t)b[0];
^ (uint64_t)(b[2] & mask) << 8;
if ( mask ) {
l ^= (uint64_t)(b[1] & mask) << 8;
}
} break; } break;
case 0: { case 0: {
l = (uint64_t)(b[1] & mask); l = ( mask ) ? (uint64_t)(b[0] & mask) : 0;
} break; } break;
} }
@ -925,19 +957,21 @@ _bsw_bytes_unsafe(ur_bsw_t *bsw, uint64_t len, uint8_t *byt)
m = byt[i] >> rest; m = byt[i] >> rest;
} }
if ( len_bit < rest ) { if ( len_bit ) {
l = byt[len_byt] & ((1 << len_bit) - 1); if ( len_bit < rest ) {
bsw->bytes[fill] = m ^ (l << off); l = byt[len_byt] & ((1 << len_bit) - 1);
off += len_bit; bsw->bytes[fill] = m ^ (l << off);
} off += len_bit;
else { }
l = byt[len_byt] & mask; else {
bsw->bytes[fill++] = m ^ (l << off); l = byt[len_byt] & mask;
bsw->bytes[fill++] = m ^ (l << off);
m = byt[len_byt] >> rest; m = byt[len_byt] >> rest;
off = len_bit - rest; off = len_bit - rest;
bsw->bytes[fill] = m & ((1 << off) - 1); bsw->bytes[fill] = m & ((1 << off) - 1);
}
} }
} }