diff options
author | Daniel Stenberg <daniel@haxx.se> | 2016-11-08 15:32:37 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2016-12-19 07:53:20 +0100 |
commit | 3ab3c16db6a5674f53cf23d56512a405fde0b2c9 (patch) | |
tree | 0c69855066ac3d7b7a6b2b60478bd4162be73735 /lib | |
parent | 60450d507f89a310c99a5039f720c18e7799b393 (diff) |
printf: fix floating point buffer overflow issues
... and add a bunch of floating point printf tests
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mprintf.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/mprintf.c b/lib/mprintf.c index a995c59a4..0dea5af62 100644 --- a/lib/mprintf.c +++ b/lib/mprintf.c @@ -92,7 +92,8 @@ # define mp_uintmax_t unsigned long #endif -#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ +#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should + fit negative DBL_MAX (317 letters) */ #define MAX_PARAMETERS 128 /* lame static limit */ #ifdef __AMIGA__ @@ -916,12 +917,25 @@ static int dprintf_formatf( *fptr = 0; if(width >= 0) { + if(width >= (long)sizeof(work)) + width = sizeof(work)-1; /* RECURSIVE USAGE */ len = curl_msnprintf(fptr, left, "%ld", width); fptr += len; left -= len; } if(prec >= 0) { + /* for each digit in the integer part, we can have one less + precision */ + size_t maxprec = sizeof(work) - 2; + double val = p->data.dnum; + while(val >= 10.0) { + val /= 10; + maxprec--; + } + + if(prec > (long)maxprec) + prec = maxprec-1; /* RECURSIVE USAGE */ len = curl_msnprintf(fptr, left, ".%ld", prec); fptr += len; @@ -941,7 +955,9 @@ static int dprintf_formatf( /* NOTE NOTE NOTE!! Not all sprintf implementations return number of output characters */ (sprintf)(work, formatbuf, p->data.dnum); - +#ifdef CURLDEBUG + assert(strlen(work) <= sizeof(work)); +#endif for(fptr=work; *fptr; fptr++) OUTCHAR(*fptr); } |