From 70351389f710e34eb7767f688e607f6738bfce03 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 26 Apr 2013 15:59:53 +0100 Subject: [PATCH] MDL-39378 Improve s() performance. These changes give about a 10% speed-up in this function. The significant changes are: 1. Simplify the if logic to remove unnecssary cases. 2. Dont pass default argument values to htmlspecialchars, just using the defaults is faster. 3. I can confirm that /i regex is faster than the equivalent regex without the i. I also added more unit tests to test the edge cases. --- lib/tests/weblib_test.php | 22 ++++++++++++++++++++-- lib/weblib.php | 12 ++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/tests/weblib_test.php b/lib/tests/weblib_test.php index 2b9eadc822d..6f94b08ea4b 100644 --- a/lib/tests/weblib_test.php +++ b/lib/tests/weblib_test.php @@ -70,9 +70,27 @@ class web_testcase extends advanced_testcase { } function test_s() { - $this->assertEquals(s("This Breaks \" Strict"), "This Breaks " Strict"); - $this->assertEquals(s("This Breaks \" Strict"), "This Breaks <a>" Strict</a>"); + // Special cases. + $this->assertSame('0', s(0)); + $this->assertSame('0', s('0')); + $this->assertSame('0', s(false)); + $this->assertSame('', s(null)); + + // Normal cases. + $this->assertEquals('This Breaks " Strict', s('This Breaks " Strict')); + $this->assertEquals('This Breaks <a>" Strict</a>', s('This Breaks " Strict')); + + // Unicode characters. + $this->assertEquals('Café', s('Café')); + $this->assertEquals('一, 二, 三', s('一, 二, 三')); + + // Don't escape already-escaped numeric entities. (Note, this behaviour + // may not be desirable. Perhaps we should remove these tests and that + // functionality, but we can only do that if we understand why it was added.) $this->assertEquals('An entity: ৿.', s('An entity: ৿.')); + $this->assertEquals('An entity: б.', s('An entity: б.')); + $this->assertEquals('An entity: &amp;.', s('An entity: &.')); + $this->assertEquals('Not an entity: &amp;#x09ff;.', s('Not an entity: &#x09ff;.')); } function test_format_text_email() { diff --git a/lib/weblib.php b/lib/weblib.php index d8c9d567a21..647504a19cd 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -85,19 +85,19 @@ define('URL_MATCH_EXACT', 2); * Returns $var with HTML characters (like "<", ">", etc.) properly quoted. * This function is very similar to {@link p()} * - * @todo Remove obsolete param $obsolete if not used anywhere - * * @param string $var the string potentially containing HTML characters - * @param boolean $obsolete no longer used. * @return string */ -function s($var, $obsolete = false) { +function s($var) { - if ($var === '0' or $var === false or $var === 0) { + if ($var === false) { return '0'; } - return preg_replace("/&#(\d+|x[0-9a-f]+);/i", "&#$1;", htmlspecialchars($var, ENT_QUOTES, 'UTF-8', true)); + // When we move to PHP 5.4 as a minimum version, change ENT_QUOTES on the + // next line to ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, and remove the + // 'UTF-8' argument. Both bring a speed-increase. + return preg_replace('/&#(\d+|x[0-9a-f]+);/i', '&#$1;', htmlspecialchars($var, ENT_QUOTES, 'UTF-8')); } /**