diff options
author | Andrea Faulds <ajf@ajf.me> | 2017-09-21 00:02:52 +0100 |
---|---|---|
committer | Andrea Faulds <ajf@ajf.me> | 2017-09-21 00:02:52 +0100 |
commit | 418f97443aa44644bdf81b96fb726518754724f5 (patch) | |
tree | 5f663a5db4b8f2ae4d3b6db12eeb0fcbba5057ac | |
parent | eedc060c92e12e054a542dc7156e31cec935a8d6 (diff) | |
download | php-git-418f97443aa44644bdf81b96fb726518754724f5.tar.gz |
Fix bug #75236
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | main/main.c | 35 | ||||
-rw-r--r-- | tests/output/bug75236.phpt | 18 |
3 files changed, 52 insertions, 4 deletions
@@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2017 PHP 7.0.25 +- Core: + . Fixed bug #75236 (infinite loop when printing an error-message). (Andrea) + - SPL: . Fixed bug #73629 (SplDoublyLinkedList::setIteratorMode masks intern flags). (J. Jeising, cmb) diff --git a/main/main.c b/main/main.c index 81e1222796..6050d0db31 100644 --- a/main/main.c +++ b/main/main.c @@ -92,6 +92,8 @@ #include "SAPI.h" #include "rfc1867.h" +#include "ext/standard/html_tables.h" + #if HAVE_MMAP || defined(PHP_WIN32) # if HAVE_UNISTD_H # include <unistd.h> @@ -124,6 +126,31 @@ PHPAPI int core_globals_id; #define SAFE_FILENAME(f) ((f)?(f):"-") +static char *get_safe_charset_hint(void) { + static char *lastHint = NULL; + static char *lastCodeset = NULL; + char *hint = SG(default_charset); + size_t len = strlen(hint); + size_t i = 0; + + if (lastHint == SG(default_charset)) { + return lastCodeset; + } + + lastHint = hint; + lastCodeset = NULL; + + for (i = 0; i < sizeof(charset_map)/sizeof(charset_map[0]); i++) { + if (len == charset_map[i].codeset_len + && zend_binary_strcasecmp(hint, len, charset_map[i].codeset, len) == 0) { + lastCodeset = (char*)charset_map[i].codeset; + break; + } + } + + return lastCodeset; +} + /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnSetPrecision) @@ -722,10 +749,10 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ buffer_len = (int)vspprintf(&buffer, 0, format, args); if (PG(html_errors)) { - replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, SG(default_charset)); + replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint()); /* Retry with substituting invalid chars on fail. */ if (!replace_buffer || ZSTR_LEN(replace_buffer) < 1) { - replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, SG(default_charset)); + replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, get_safe_charset_hint()); } efree(buffer); @@ -792,7 +819,7 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ } if (PG(html_errors)) { - replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, SG(default_charset)); + replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, get_safe_charset_hint()); efree(origin); origin = ZSTR_VAL(replace_origin); } @@ -1106,7 +1133,7 @@ static ZEND_COLD void php_error_cb(int type, const char *error_filename, const u if (PG(html_errors)) { if (type == E_ERROR || type == E_PARSE) { - zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, SG(default_charset)); + zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint()); php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(buf), error_filename, error_lineno, STR_PRINT(append_string)); zend_string_free(buf); } else { diff --git a/tests/output/bug75236.phpt b/tests/output/bug75236.phpt new file mode 100644 index 0000000000..f6c7a51aa3 --- /dev/null +++ b/tests/output/bug75236.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #75236: infinite loop when printing an error-message +--FILE-- +<?php + + ini_set('html_errors', true); + ini_set('default_charset', 'ISO-8859-2'); + + printf ("before getfilecontent\n"); + file_get_contents ('no/suchfile'); + printf ("after getfilecontent\n"); + +?> +--EXPECTF-- +before getfilecontent +<br /> +<b>Warning</b>: file_get_contents(no/suchfile): failed to open stream: No such file or directory in <b>%s</b> on line <b>7</b><br /> +after getfilecontent |