In the floating-point hex (%a) code, it checks whether the requested
precision is smaller than the hex buf size. It does this by casting
(precis + 1) to signed. Since precis can be any user-supplied value,
this can wrap. Instead, cast the (buffer_length - 1) to unsigned, since
this is bounded to a small constant value > 1.
In practise this makes no difference currently, as a large precis will
have caused a malloc panic earlier anyway. But that might change in
future.
if (has_precis) {
U8* ve = (subnormal ? vlnz + 1 : vend);
SSize_t vn = ve - v0;
- if ((SSize_t)(precis + 1) < vn) {
+ assert(vn >= 1);
+ if (precis < (Size_t)(vn - 1)) {
bool overflow = FALSE;
if (v0[precis + 1] < 0x8) {
/* Round down, nothing to do. */