Hi,
I used Shopify/ruby_memcheck to check for memory issues in bio-twobit, and Valgrind reported the following:
Invalid write of size 1
*bytes2bases (2bit.c:73)
It seems this occurs when seq buffer size (sz) is too small for the output, causing out-of-bounds writes. Adding a check for buffer size at the start of bytes2bases could resolve this by preventing writes when sz is insufficient.
|
void bytes2bases(char *seq, uint8_t *byte, uint32_t sz, int offset) { |
|
uint32_t pos = 0, remainder = 0, i = 0; |
|
char bases[4] = "TCAG"; |
|
uint8_t foo = byte[0]; |
|
|
|
// Deal with the first partial byte |
|
if(offset != 0) { |
|
while(offset < 4) { |
|
seq[pos++] = byte2base(foo, offset++); |
|
} |
|
if(pos >= sz) return; |
|
foo = byte[++i]; |
|
} |
|
|
|
// Deal with everything else, with the possible exception of the last fractional byte |
|
remainder = (sz - pos) % 4; |
|
while(pos < sz - remainder) { |
|
foo = byte[i++]; |
|
seq[pos + 3] = bases[foo & 3]; |
|
foo >>= 2; |
|
seq[pos + 2] = bases[foo & 3]; |
|
foo >>= 2; |
|
seq[pos + 1] = bases[foo & 3]; |
|
foo >>= 2; |
|
seq[pos] = bases[foo & 3]; |
|
foo >>= 2; |
|
pos += 4; |
|
} |
|
|
|
// Deal with the last partial byte |
|
if(remainder > 0) foo = byte[i]; |
|
for(offset=0; offset<remainder; offset++) { |
|
seq[pos++] = byte2base(foo, offset); |
|
} |
|
} |
Thanks for your work on this library!
Hi,
I used Shopify/ruby_memcheck to check for memory issues in bio-twobit, and Valgrind reported the following:
It seems this occurs when
seqbuffer size (sz) is too small for the output, causing out-of-bounds writes. Adding a check for buffer size at the start ofbytes2basescould resolve this by preventing writes whenszis insufficient.lib2bit/2bit.c
Lines 65 to 99 in 9fc78d6
Thanks for your work on this library!