diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-07 15:46:08 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-07 15:46:08 +0200 |
commit | c50cfc4d3d60e69040c9d2f3836b12e886b587ac (patch) | |
tree | 3998a9c64bdfadac5be8ab22f49695c43d47112d /main/main.c | |
parent | d6ac8b236f9ffb120562b5d23dfcac833182063c (diff) | |
download | php-git-c50cfc4d3d60e69040c9d2f3836b12e886b587ac.tar.gz |
Add quiet parameter to internal HTML entities API
In some places, we need to make sure that no warnings are thrown
due to unknown encoding. The error reporting code tried to avoid
this by determining a "safe charset", but this introduces subtle
discrepancies in which charset is picked (normally
internal_encoding takes precedence). Avoid this by suppressing
the warning in the first place.
While here, use the fallback logic to print error messages with
substitution characters more consistently, to avoid skipping
parts of the error message entirely.
Diffstat (limited to 'main/main.c')
-rw-r--r-- | main/main.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/main/main.c b/main/main.c index dc9182e481..98aaa5bece 100644 --- a/main/main.c +++ b/main/main.c @@ -95,31 +95,6 @@ PHPAPI size_t core_globals_offset; #define SAFE_FILENAME(f) ((f)?(f):"-") -static char *get_safe_charset_hint(void) { - ZEND_TLS char *lastHint = NULL; - ZEND_TLS 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(OnSetFacility) @@ -937,6 +912,19 @@ PHPAPI size_t php_printf(const char *format, ...) } /* }}} */ +static zend_string *escape_html(const char *buffer, size_t buffer_len) { + zend_string *result = php_escape_html_entities_ex( + (const unsigned char *) buffer, buffer_len, 0, ENT_COMPAT, + /* charset_hint */ NULL, /* double_encode */ 1, /* quiet */ 1); + if (!result || ZSTR_LEN(result) == 0) { + /* Retry with substituting invalid chars on fail. */ + result = php_escape_html_entities_ex( + (const unsigned char *) buffer, buffer_len, 0, ENT_COMPAT | ENT_HTML_SUBSTITUTE_ERRORS, + /* charset_hint */ NULL, /* double_encode */ 1, /* quiet */ 1); + } + return result; +} + /* {{{ php_verror */ /* php_verror is called from php_error_docref<n> functions. * Its purpose is to unify error messages and automatically generate clickable @@ -962,12 +950,7 @@ 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, 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, get_safe_charset_hint()); - } - + replace_buffer = escape_html(buffer, buffer_len); efree(buffer); if (replace_buffer) { @@ -1032,7 +1015,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, get_safe_charset_hint()); + replace_origin = escape_html(origin, origin_len); efree(origin); origin = ZSTR_VAL(replace_origin); } @@ -1335,7 +1318,7 @@ static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, co 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, get_safe_charset_hint()); + zend_string *buf = escape_html(buffer, buffer_len); php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%" PRIu32 "</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 { |