Backported from 5.6.27 by Remi. From 631173aa5c716f6d4a7bf1f6b7295482a46823bc Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 3 Oct 2016 18:06:59 -0700 Subject: [PATCH] Really fix bug #73017 --- ext/standard/string.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index 9acbe03..cb6a8b4 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -891,11 +891,12 @@ PHP_FUNCTION(wordwrap) { const char *text, *breakchar = "\n"; char *newtext; - int textlen, breakcharlen = 1, newtextlen, chk; + int textlen, breakcharlen = 1, chk; size_t alloced; - long current = 0, laststart = 0, lastspace = 0; + size_t current = 0, laststart = 0, lastspace = 0; long linelength = 75; zend_bool docut = 0; + size_t newtextlen; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lsb", &text, &textlen, &linelength, &breakchar, &breakcharlen, &docut) == FAILURE) { return; @@ -915,6 +916,11 @@ PHP_FUNCTION(wordwrap) RETURN_FALSE; } + if (linelength < 0 || linelength > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be between 0 and %d", INT_MAX); + RETURN_FALSE; + } + /* Special case for a single-character break as it needs no additional storage space */ if (breakcharlen == 1 && !docut) { @@ -942,10 +948,10 @@ PHP_FUNCTION(wordwrap) if (linelength > 0) { chk = (int)(textlen/linelength + 1); newtext = safe_emalloc(chk, breakcharlen, textlen + 1); - alloced = textlen + chk * breakcharlen + 1; + alloced = (size_t)textlen + chk * (size_t)breakcharlen + 1; } else { chk = textlen; - alloced = textlen * (breakcharlen + 1) + 1; + alloced = (size_t)textlen * ((size_t)breakcharlen + 1) + 1; newtext = safe_emalloc(textlen, (breakcharlen + 1), 1); } -- 2.1.4 From 8ea01d5f19a68a3f062c1e5d735372f8a48cbba8 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 3 Oct 2016 19:17:42 -0700 Subject: [PATCH] Apparently negative wordwrap is a thing and should work as length = 0. I'll leave it as is for now. --- ext/standard/string.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index cb6a8b4..abe4eb1 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -916,7 +916,11 @@ PHP_FUNCTION(wordwrap) RETURN_FALSE; } - if (linelength < 0 || linelength > INT_MAX) { + if (linelength < 0) { + /* For BC */ + linelength = 0; + } + if (linelength > INT_MAX) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be between 0 and %d", INT_MAX); RETURN_FALSE; } -- 2.1.4