Skip to content

Commit 624538b

Browse files
committed
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.
1 parent f047174 commit 624538b

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

missing/dtoa.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,29 @@
210210
#include <locale.h>
211211
#endif
212212

213+
#if defined(HAVE_STDCKDINT_H) || !defined(__has_include)
214+
#elif __has_include(<stdckdint.h>)
215+
# define HAVE_STDCKDINT_H 1
216+
#endif
217+
#ifdef HAVE_STDCKDINT_H
218+
# include <stdckdint.h>
219+
#endif
220+
221+
#if !defined(ckd_add)
222+
static inline int /* bool */
223+
ckd_add(int *result, int x, int y)
224+
{
225+
if (x < 0) {
226+
if (y < INT_MIN - x) return 1;
227+
}
228+
else if (x > 0) {
229+
if (y > INT_MAX - x) return 1;
230+
}
231+
*result = x + y;
232+
return 0;
233+
}
234+
#endif
235+
213236
#ifdef MALLOC
214237
extern void *MALLOC(size_t);
215238
#else
@@ -2841,7 +2864,10 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
28412864
leftright = 0;
28422865
/* no break */
28432866
case 5:
2844-
i = ndigits + k + 1;
2867+
if (ckd_add(&i, ndigits, k + 1)) { /* k + 1 should be safe */
2868+
Bfree(b);
2869+
return NULL;
2870+
}
28452871
ilim = i;
28462872
ilim1 = i - 1;
28472873
if (i <= 0)

0 commit comments

Comments
 (0)