From: Gustavo André dos Santos Lopes Date: Mon, 21 Feb 2011 06:53:24 +0000 (+0000) Subject: - Fixed bug #54055 (buffer overrun with high values for precision ini X-Git-Tag: php-5.3.6RC2~21 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b2d14c5e10cc024f97a257a00fbefdb3a906501;p=php - 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. --- diff --git a/NEWS b/NEWS index 0bc73ddb6b..a1a780a64e 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,8 @@ authentication using stream_context/http/header/Proxy-Authorization (Dmitry) . Changed default value of ini directive serialize_precision from 100 to 17. (Gustavo) + . Fixed bug #54055 (buffer overrun with high values for precision ini + setting). (Gustavo) . Fixed bug #53959 (reflection data for fgetcsv out-of-date). (Richard) . Fixed bug #53577 (Regression introduced in 5.3.4 in open_basedir with a trailing forward slash). (lekensteyn at gmail dot com, Pierre) diff --git a/ext/standard/tests/strings/bug54055.phpt b/ext/standard/tests/strings/bug54055.phpt new file mode 100644 index 0000000000..7124c46875 --- /dev/null +++ b/ext/standard/tests/strings/bug54055.phpt @@ -0,0 +1,589 @@ +--TEST-- +Bug #54055: PHP crashes when executing strval when precision setting is very high +--FILE-- + 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 | + | Author: Stig Sæther Bakken | | Marcus Boerger | +----------------------------------------------------------------------+ */ @@ -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