Skip to content

Commit 418f974

Browse files
Fix bug #75236
1 parent eedc060 commit 418f974

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2017 PHP 7.0.25
44

5+
- Core:
6+
. Fixed bug #75236 (infinite loop when printing an error-message). (Andrea)
7+
58
- SPL:
69
. Fixed bug #73629 (SplDoublyLinkedList::setIteratorMode masks intern flags).
710
(J. Jeising, cmb)

main/main.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
#include "SAPI.h"
9393
#include "rfc1867.h"
9494

95+
#include "ext/standard/html_tables.h"
96+
9597
#if HAVE_MMAP || defined(PHP_WIN32)
9698
# if HAVE_UNISTD_H
9799
# include <unistd.h>
@@ -124,6 +126,31 @@ PHPAPI int core_globals_id;
124126

125127
#define SAFE_FILENAME(f) ((f)?(f):"-")
126128

129+
static char *get_safe_charset_hint(void) {
130+
static char *lastHint = NULL;
131+
static char *lastCodeset = NULL;
132+
char *hint = SG(default_charset);
133+
size_t len = strlen(hint);
134+
size_t i = 0;
135+
136+
if (lastHint == SG(default_charset)) {
137+
return lastCodeset;
138+
}
139+
140+
lastHint = hint;
141+
lastCodeset = NULL;
142+
143+
for (i = 0; i < sizeof(charset_map)/sizeof(charset_map[0]); i++) {
144+
if (len == charset_map[i].codeset_len
145+
&& zend_binary_strcasecmp(hint, len, charset_map[i].codeset, len) == 0) {
146+
lastCodeset = (char*)charset_map[i].codeset;
147+
break;
148+
}
149+
}
150+
151+
return lastCodeset;
152+
}
153+
127154
/* {{{ PHP_INI_MH
128155
*/
129156
static PHP_INI_MH(OnSetPrecision)
@@ -722,10 +749,10 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ
722749
buffer_len = (int)vspprintf(&buffer, 0, format, args);
723750

724751
if (PG(html_errors)) {
725-
replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, SG(default_charset));
752+
replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint());
726753
/* Retry with substituting invalid chars on fail. */
727754
if (!replace_buffer || ZSTR_LEN(replace_buffer) < 1) {
728-
replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, SG(default_charset));
755+
replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, get_safe_charset_hint());
729756
}
730757

731758
efree(buffer);
@@ -792,7 +819,7 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ
792819
}
793820

794821
if (PG(html_errors)) {
795-
replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, SG(default_charset));
822+
replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, get_safe_charset_hint());
796823
efree(origin);
797824
origin = ZSTR_VAL(replace_origin);
798825
}
@@ -1106,7 +1133,7 @@ static ZEND_COLD void php_error_cb(int type, const char *error_filename, const u
11061133

11071134
if (PG(html_errors)) {
11081135
if (type == E_ERROR || type == E_PARSE) {
1109-
zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, SG(default_charset));
1136+
zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, get_safe_charset_hint());
11101137
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));
11111138
zend_string_free(buf);
11121139
} else {

tests/output/bug75236.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #75236: infinite loop when printing an error-message
3+
--FILE--
4+
<?php
5+
6+
ini_set('html_errors', true);
7+
ini_set('default_charset', 'ISO-8859-2');
8+
9+
printf ("before getfilecontent\n");
10+
file_get_contents ('no/suchfile');
11+
printf ("after getfilecontent\n");
12+
13+
?>
14+
--EXPECTF--
15+
before getfilecontent
16+
<br />
17+
<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 />
18+
after getfilecontent

0 commit comments

Comments
 (0)