Backported from 5.6.27 by Remi. From 8259130b6bc752968856b352c9e7f8e03a8c0a8e Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 10 Oct 2016 23:42:50 -0700 Subject: [PATCH] Fix for #73240 - Write out of bounds at number_format --- ext/standard/math.c | 108 +++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/ext/standard/math.c b/ext/standard/math.c index 5ffeff7..8290b20 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1099,13 +1099,13 @@ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char tho static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len, - int *result_len) + size_t *result_len) { char *tmpbuf = NULL, *resbuf; char *s, *t; /* source, target */ char *dp; - int integral; - int tmplen, reslen=0; + size_t integral; + size_t tmplen, reslen=0; int count=0; int is_negative=0; @@ -1144,15 +1144,23 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, /* allow for thousand separators */ if (thousand_sep) { + if (integral + thousand_sep_len * ((integral-1) / 3) < integral) { + /* overflow */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); + } integral += thousand_sep_len * ((integral-1) / 3); } - + reslen = integral; - + if (dec) { reslen += dec; if (dec_point) { + if (reslen + dec_point < dec_point) { + /* overflow */ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); + } reslen += dec_point_len; } } @@ -1235,17 +1243,21 @@ PHP_FUNCTION(number_format) char *thousand_sep = NULL, *dec_point = NULL; char thousand_sep_chr = ',', dec_point_chr = '.'; int thousand_sep_len = 0, dec_point_len = 0; - + char *formatted; + size_t formatted_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) { return; } switch(ZEND_NUM_ARGS()) { case 1: - RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0); + formatted = _php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr); + formatted_len = strlen(formatted); break; case 2: - RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0); + formatted = _php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr); + formatted_len = strlen(formatted); break; case 4: if (dec_point == NULL) { @@ -1258,15 +1270,15 @@ PHP_FUNCTION(number_format) thousand_sep_len = 1; } - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec, + formatted = _php_math_number_format_ex_len(num, dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len, - &Z_STRLEN_P(return_value)); + &formatted_len); break; default: WRONG_PARAM_COUNT; - break; + return; } + RETVAL_STRINGL_CHECK(formatted, formatted_len, 0); } /* }}} */ -- 2.1.4 From c1112ff323c9dd1a4596aa4272e918acf0f797eb Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 11 Oct 2016 14:39:16 -0700 Subject: [PATCH] fix tsrm --- ext/standard/math.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/math.c b/ext/standard/math.c index 8290b20..bb64425 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1146,7 +1146,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, if (thousand_sep) { if (integral + thousand_sep_len * ((integral-1) / 3) < integral) { /* overflow */ - php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); + zend_error(E_ERROR, "String overflow"); } integral += thousand_sep_len * ((integral-1) / 3); } @@ -1159,7 +1159,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, if (dec_point) { if (reslen + dec_point < dec_point) { /* overflow */ - php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow"); + zend_error(E_ERROR, "String overflow"); } reslen += dec_point_len; } -- 2.1.4