- Standard:
. version_compare() no longer accepts undocumented operator abbreviations.
+ . htmlspecialchars(), htmlentities(), htmlspecialchars_decode(),
+ html_entitity_decode() and get_html_translation_table() now use
+ ENT_QUOTES | ENT_SUBSTITUTE rather than ENT_COMPAT by default. This means
+ that ' is escaped to ' while previously it was left alone.
+ Additionally, malformed UTF-8 will be replaced by a Unicode substitution
+ character, instead of resulting in an empty string.
========================================
2. New Features
/* {{{ html.c */
-function htmlspecialchars(string $string, int $flags = ENT_COMPAT, ?string $encoding = null, bool $double_encode = true): string {}
+function htmlspecialchars(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE, ?string $encoding = null, bool $double_encode = true): string {}
-function htmlspecialchars_decode(string $string, int $flags = ENT_COMPAT): string {}
+function htmlspecialchars_decode(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE): string {}
-function html_entity_decode(string $string, int $flags = ENT_COMPAT, ?string $encoding = null): string {}
+function html_entity_decode(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE, ?string $encoding = null): string {}
-function htmlentities(string $string, int $flags = ENT_COMPAT, ?string $encoding = null, bool $double_encode = true): string {}
+function htmlentities(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE, ?string $encoding = null, bool $double_encode = true): string {}
-function get_html_translation_table(int $table = HTML_SPECIALCHARS, int $flags = ENT_COMPAT, string $encoding = "UTF-8"): array {}
+function get_html_translation_table(int $table = HTML_SPECIALCHARS, int $flags = ENT_QUOTES | ENT_SUBSTITUTE, string $encoding = "UTF-8"): array {}
/* }}} */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_htmlspecialchars, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_COMPAT")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_QUOTES | ENT_SUBSTITUTE")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, double_encode, _IS_BOOL, 0, "true")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_htmlspecialchars_decode, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_COMPAT")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_QUOTES | ENT_SUBSTITUTE")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_html_entity_decode, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_COMPAT")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_QUOTES | ENT_SUBSTITUTE")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_html_translation_table, 0, 0, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, table, IS_LONG, 0, "HTML_SPECIALCHARS")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_COMPAT")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "ENT_QUOTES | ENT_SUBSTITUTE")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"UTF-8\"")
ZEND_END_ARG_INFO()
static void php_html_entities(INTERNAL_FUNCTION_PARAMETERS, int all)
{
zend_string *str, *hint_charset = NULL;
- zend_long flags = ENT_COMPAT;
+ zend_long flags = ENT_QUOTES|ENT_SUBSTITUTE;
zend_string *replaced;
bool double_encode = 1;
PHP_FUNCTION(htmlspecialchars_decode)
{
zend_string *str;
- zend_long quote_style = ENT_COMPAT;
+ zend_long quote_style = ENT_QUOTES|ENT_SUBSTITUTE;
zend_string *replaced;
ZEND_PARSE_PARAMETERS_START(1, 2)
PHP_FUNCTION(html_entity_decode)
{
zend_string *str, *hint_charset = NULL;
- zend_long quote_style = ENT_COMPAT;
+ zend_long quote_style = ENT_QUOTES|ENT_SUBSTITUTE;
zend_string *replaced;
ZEND_PARSE_PARAMETERS_START(1, 3)
PHP_FUNCTION(get_html_translation_table)
{
zend_long all = HTML_SPECIALCHARS,
- flags = ENT_COMPAT;
+ flags = ENT_QUOTES|ENT_SUBSTITUTE;
int doctype;
entity_table_opt entity_table;
const enc_to_uni *to_uni_table = NULL;
- Parameters [4] {
Parameter #0 [ <required> string $string ]
- Parameter #1 [ <optional> int $flags = ENT_COMPAT ]
+ Parameter #1 [ <optional> int $flags = ENT_QUOTES | ENT_SUBSTITUTE ]
Parameter #2 [ <optional> ?string $encoding = null ]
Parameter #3 [ <optional> bool $double_encode = true ]
}
- Parameters [3] {
Parameter #0 [ <optional> int $table = HTML_SPECIALCHARS ]
- Parameter #1 [ <optional> int $flags = ENT_COMPAT ]
+ Parameter #1 [ <optional> int $flags = ENT_QUOTES | ENT_SUBSTITUTE ]
Parameter #2 [ <optional> string $encoding = "UTF-8" ]
}
- Return [ array ]
 NOT DECODED
 NOT DECODED
  DECODED
-' NOT DECODED
+' DECODED
 NOT DECODED
€ NOT DECODED
Ÿ NOT DECODED
string(42) "<html> This is a test! </html>"
*** Testing htmlentites() on a quote ***
-string(36) "A 'quote' is <b>bold</b>"
+string(46) "A 'quote' is <b>bold</b>"
string(46) "A 'quote' is <b>bold</b>"
string(36) "A 'quote' is <b>bold</b>"
string(36) "A 'quote' is <b>bold</b>"
string(46) "<br>Testing<p>New file.</p> "
*** Testing htmlspecialchars() on a quote...
-string(36) "A 'quote' is <b>bold</b>"
+string(46) "A 'quote' is <b>bold</b>"
string(46) "A 'quote' is <b>bold</b>"
string(36) "A 'quote' is <b>bold</b>"
string(36) "A 'quote' is <b>bold</b>"
Test 1: abc<>"&
Test 2: &&abc<>"&
Test 3: a>,\<bc<>"&
-Test 4: a\'\'&bc<>"&
+Test 4: a\'\'&bc<>"&
Test 5: &amp;&lt;
Test 6: abc<>"&
Test 7: &&abc<>"&
?>
--EXPECT--
*** Testing htmlspecialchars_decode() : basic functionality ***
-string(92) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
-string(92) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
+string(82) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
+string(82) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
string(92) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
string(92) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
string(102) "Roy's height > Sam's height. 13 < 25. 1111 & 0000 = 0000. " double quoted string ""
-- Iteration 2 --
string(0) ""
-- Iteration 3 --
-string(103) "<html>Roy's height > Sam's height
+string(93) "<html>Roy's height > Sam's height
13 < 25
1111 & 0000 = 0000
"This is a double quoted string""
-- Iteration 4 --
-string(130) "<html>Roy's height\r > Sam 's height
+string(120) "<html>Roy's height\r > Sam 's height
1111 & 0000\v\v = \f0000
" heredoc
double quoted string. with\vdifferent\fwhite\vspaces""
"string" 1111 & 0000 = 0000
;"
-- Iteration 6 --
-string(153) "<html>< This's a string with quotes:
+string(143) "<html>< This's a string with quotes:
"strings in double quote" &
'strings in single quote' "
-this\line is 'single quoted' /with\slashes </html>"
+this\line is 'single quoted' /with\slashes </html>"
Done
--EXPECT--
*** Testing htmlspecialchars_decode() : usage variations ***
-- Iteration 1 --
-string(90) "Roy's height > Sam's \$height... 1111 ≈ 0000 = 0000... " double quote string ""
+string(85) "Roy's height > Sam's \$height... 1111 ≈ 0000 = 0000... " double quote string ""
string(90) "Roy's height > Sam's \$height... 1111 ≈ 0000 = 0000... " double quote string ""
string(100) "Roy's height > Sam's \$height... 1111 ≈ 0000 = 0000... " double quote string ""
string(85) "Roy's height > Sam's \$height... 1111 ≈ 0000 = 0000... " double quote string ""
-- Iteration 2 --
-string(88) "Roy's height > Sam's height... \t\t 13 < 15...\n\r " double quote\f\v string ""
+string(78) "Roy's height > Sam's height... \t\t 13 < 15...\n\r " double quote\f\v string ""
string(88) "Roy's height > Sam's height... \t\t 13 < 15...\n\r " double quote\f\v string ""
string(98) "Roy's height > Sam's height... \t\t 13 < 15...\n\r " double quote\f\v string ""
string(78) "Roy's height > Sam's height... \t\t 13 < 15...\n\r " double quote\f\v string ""
-- Iteration 3 --
-string(48) "\nRoy's height >\t; Sam's\v height\f"
+string(38) "\nRoy's height >\t; Sam's\v height\f"
string(48) "\nRoy's height >\t; Sam's\v height\f"
string(48) "\nRoy's height >\t; Sam's\v height\f"
string(38) "\nRoy's height >\t; Sam's\v height\f"
-- Iteration 4 --
-string(48) "\r\tRoy's height >\r; Sam\t's height"
+string(38) "\r\tRoy's height >\r; Sam\t's height"
string(48) "\r\tRoy's height >\r; Sam\t's height"
string(48) "\r\tRoy's height >\r; Sam\t's height"
string(38) "\r\tRoy's height >\r; Sam\t's height"
--EXPECT--
*** Testing htmlspecialchars_decode() : usage variations ***
-- Iteration 1 --
-string(89) "Roy's height > Sam's $height... 1111 ≈ 0000 = 0000... " double quote string ""
+string(84) "Roy's height > Sam's $height... 1111 ≈ 0000 = 0000... " double quote string ""
string(89) "Roy's height > Sam's $height... 1111 ≈ 0000 = 0000... " double quote string ""
string(99) "Roy's height > Sam's $height... 1111 ≈ 0000 = 0000... " double quote string ""
string(84) "Roy's height > Sam's $height... 1111 ≈ 0000 = 0000... " double quote string ""
-- Iteration 2 --
-string(82) "Roy's height > Sam's height... 13 < 15...
+string(72) "Roy's height > Sam's height... 13 < 15...
\r " double quote\f\v string ""
string(82) "Roy's height > Sam's height... 13 < 15...
\r " double quote\f\v string ""
string(72) "Roy's height > Sam's height... 13 < 15...
\r " double quote\f\v string ""
-- Iteration 3 --
-string(44) "
-Roy's height > ; Sam's\v height\f"
+string(34) "
+Roy's height > ; Sam's\v height\f"
string(44) "
Roy's height > ; Sam's\v height\f"
string(44) "
string(34) "
Roy's height > ; Sam's\v height\f"
-- Iteration 4 --
-string(44) "\r Roy's height >\r; Sam 's height"
+string(34) "\r Roy's height >\r; Sam 's height"
string(44) "\r Roy's height >\r; Sam 's height"
string(44) "\r Roy's height >\r; Sam 's height"
string(34) "\r Roy's height >\r; Sam 's height"