dtoa.c: Check integer underflow

Reported at https://hackerone.com/reports/3288162

This underflow does not occur in Ruby because:

* This function is `static` and not accessible other than from ruby
  internal.

* Ruby uses mode 0 when calling this function directly.

* For `%f` in vsnprintf.c using mode 3, this parameter comes from the
  precision, but negative precision is meaningless and ignored.
This commit is contained in:
Nobuyoshi Nakada 2025-09-10 12:57:34 +09:00
parent f047174cf1
commit 624538ba92
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465

View File

@ -210,6 +210,29 @@
#include <locale.h>
#endif
#if defined(HAVE_STDCKDINT_H) || !defined(__has_include)
#elif __has_include(<stdckdint.h>)
# define HAVE_STDCKDINT_H 1
#endif
#ifdef HAVE_STDCKDINT_H
# include <stdckdint.h>
#endif
#if !defined(ckd_add)
static inline int /* bool */
ckd_add(int *result, int x, int y)
{
if (x < 0) {
if (y < INT_MIN - x) return 1;
}
else if (x > 0) {
if (y > INT_MAX - x) return 1;
}
*result = x + y;
return 0;
}
#endif
#ifdef MALLOC
extern void *MALLOC(size_t);
#else
@ -2841,7 +2864,10 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
leftright = 0;
/* no break */
case 5:
i = ndigits + k + 1;
if (ckd_add(&i, ndigits, k + 1)) { /* k + 1 should be safe */
Bfree(b);
return NULL;
}
ilim = i;
ilim1 = i - 1;
if (i <= 0)