diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 81ac9a3ca09..7e4e2e4f049 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -6,6 +6,7 @@ Yii Framework 2 Change Log - Bug #14663: Do not convert int to string if database type of a column is numeric (egorrishe) - Bug #18650: Refactor `framework/assets/yii.activeForm.js` arrow function into traditional function for IE11 compatibility (marcovtwout) +- Bug #18749: Fix `yii\web\ErrorHandler::encodeHtml()` to support strings with invalid UTF symbols (vjik) - Enh #18724: Allow jQuery 3.6 to be installed (marcovtwout) - Enh #18628: Added strings "software", and "hardware" to `$specials` array in `yii\helpers\BaseInflector` (kjusupov) - Enh #18653: Added method `yii\helpers\BaseHtml::getInputIdByName()` (WinterSilence) diff --git a/framework/web/ErrorHandler.php b/framework/web/ErrorHandler.php index 8c9ee2728f9..0d573ad7927 100644 --- a/framework/web/ErrorHandler.php +++ b/framework/web/ErrorHandler.php @@ -180,7 +180,7 @@ protected function convertExceptionToArray($exception) */ public function htmlEncode($text) { - return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); + return htmlspecialchars($text, ENT_NOQUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8'); } /** diff --git a/tests/framework/web/ErrorHandlerTest.php b/tests/framework/web/ErrorHandlerTest.php index 14db1af0cb1..9fdd41fcb6d 100644 --- a/tests/framework/web/ErrorHandlerTest.php +++ b/tests/framework/web/ErrorHandlerTest.php @@ -79,6 +79,61 @@ public function testRenderCallStackItem() $this->assertContains('', $out); } + + public function dataHtmlEncode() + { + return [ + [ + "a \t=<>&\"'\x80`\n", + "a \t=<>&\"'�`\n", + ], + [ + 'test', + '<b>test</b>', + ], + [ + '"hello"', + '"hello"', + ], + [ + "'hello world'", + "'hello world'", + ], + [ + 'Chip&Dale', + 'Chip&amp;Dale', + ], + [ + "\t\$x=24;", + "\t\$x=24;", + ], + ]; + } + + /** + * @dataProvider dataHtmlEncode + */ + public function testHtmlEncode($text, $expected) + { + $handler = Yii::$app->getErrorHandler(); + + $this->assertSame($expected, $handler->htmlEncode($text)); + } + + public function testHtmlEncodeWithUnicodeSequence() + { + if (PHP_VERSION_ID < 70000) { + $this->markTestSkipped('Can not be tested on PHP < 7.0'); + return; + } + + $handler = Yii::$app->getErrorHandler(); + + $text = "a \t=<>&\"'\x80\u{20bd}`\u{000a}\u{000c}\u{0000}"; + $expected = "a \t=<>&\"'�₽`\n\u{000c}\u{0000}"; + + $this->assertSame($expected, $handler->htmlEncode($text)); + } } class ErrorHandler extends \yii\web\ErrorHandler