diff options
| author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-02-21 06:53:24 +0000 |
|---|---|---|
| committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-02-21 06:53:24 +0000 |
| commit | 2a6968e43ae4dc6b91c44f59daa94b3a2b26fd51 (patch) | |
| tree | 1e78200fc3e0fc0d32e11987fe223a803568166a /main | |
| parent | b21f62eb2d833bd435a13289a85e29c559ee9d74 (diff) | |
| download | php-git-2a6968e43ae4dc6b91c44f59daa94b3a2b26fd51.tar.gz | |
- Fixed bug #54055 (buffer overrun with high values for precision ini
setting).
#This fix (for g/G/k/H modes) is done at a different level than that for the
#modes e/E/f/F, at a bit higher level and therefore with less coverage. I
#chose this because it addresses the problem where it is -- the calling function
#that passes a buffer too small to php_gcvt.
Diffstat (limited to 'main')
| -rw-r--r-- | main/snprintf.c | 8 | ||||
| -rw-r--r-- | main/snprintf.h | 13 | ||||
| -rw-r--r-- | main/spprintf.c | 8 |
3 files changed, 20 insertions, 9 deletions
diff --git a/main/snprintf.c b/main/snprintf.c index 0e052baa6a..a1b253cfda 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -677,10 +677,6 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / /* * Check if a precision was specified - * - * XXX: an unreasonable amount of precision may be specified - * resulting in overflow of num_buf. Currently we - * ignore this possibility. */ if (*fmt == '.') { adjust_precision = YES; @@ -694,6 +690,10 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / precision = 0; } else precision = 0; + + if (precision > FORMAT_CONV_MAX_PRECISION) { + precision = FORMAT_CONV_MAX_PRECISION; + } } else adjust_precision = NO; } else diff --git a/main/snprintf.h b/main/snprintf.h index 41fed76dd1..2bf7c2c180 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Stig Sæther Bakken <ssb@php.net> | + | Author: Stig Sæther Bakken <ssb@php.net> | | Marcus Boerger <helly@php.net> | +----------------------------------------------------------------------+ */ @@ -158,6 +158,17 @@ extern char * ap_php_conv_10(register wide_int num, register bool_int is_unsigne extern char * ap_php_conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len); +/* The maximum precision that's allowed for float conversion. Does not include + * decimal separator, exponent, sign, terminator. Currently does not affect + * the modes e/f, only g/k/H, as those have a different limit enforced at + * another level (see NDIG in php_conv_fp()). + * Applies to the formatting functions of both spprintf.c and snprintf.c, which + * use equally sized buffers of MAX_BUF_SIZE = 512 to hold the result of the + * call to php_gcvt(). + * This should be reasonably smaller than MAX_BUF_SIZE (I think MAX_BUF_SIZE - 9 + * should be enough, but let's give some more space) */ +#define FORMAT_CONV_MAX_PRECISION 500 + #endif /* SNPRINTF_H */ /* diff --git a/main/spprintf.c b/main/spprintf.c index 635d17ca17..8c90fda378 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -285,10 +285,6 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* * Check if a precision was specified - * - * XXX: an unreasonable amount of precision may be specified - * resulting in overflow of num_buf. Currently we - * ignore this possibility. */ if (*fmt == '.') { adjust_precision = YES; @@ -302,6 +298,10 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) precision = 0; } else precision = 0; + + if (precision > FORMAT_CONV_MAX_PRECISION) { + precision = FORMAT_CONV_MAX_PRECISION; + } } else adjust_precision = NO; } else |
