From 88f46b162b3bf9bc9a7a1d3d7280f702f5b9f501 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 5 Jul 2012 20:14:49 +0200 Subject: [PATCH 1/2] Fix potential integer overflow in bin2hex The code was already using safe_emalloc but did the multiplication in the first argument, thus making the use of safe_emalloc pretty useless. The *2 is now moved to the second argument. --- ext/standard/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index e3fc27e7e22..a521d78261b 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -131,7 +131,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * register unsigned char *result = NULL; size_t i, j; - result = (unsigned char *) safe_emalloc(oldlen * 2, sizeof(char), 1); + result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1); for (i = j = 0; i < oldlen; i++) { result[j++] = hexconvtab[old[i] >> 4]; From 157ddd95773114c1148536b4b32fcbedf0c79b20 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 5 Jul 2012 20:31:58 +0200 Subject: [PATCH 2/2] Fix potential integer overflow in nl2br The buffer size was calculated manually, thus creating integer overflows for very large inputs, e.g. nl2br(str_repeat("\n", 613566757)). The code now uses safe_emalloc, thus making the code throw an error instead of crashing. --- ext/standard/string.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index a521d78261b..1a7bd1e0b47 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4001,13 +4001,12 @@ PHP_FUNCTION(nl2br) RETURN_STRINGL(str, str_len, 1); } - if (is_xhtml) { - new_length = str_len + repl_cnt * (sizeof("
") - 1); - } else { - new_length = str_len + repl_cnt * (sizeof("
") - 1); - } + { + size_t repl_len = is_xhtml ? (sizeof("
") - 1) : (sizeof("
") - 1); - tmp = target = emalloc(new_length + 1); + new_length = str_len + repl_cnt * repl_len; + tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1); + } while (str < end) { switch (*str) {