From 61b219953ada83783b1cf97151b6a16260494462 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Sun, 3 Sep 2023 18:01:19 +0200 Subject: [PATCH] encoding.html: optimize escape performance (#19264) --- vlib/encoding/html/escape.v | 9 +++++++-- vlib/encoding/html/escape_test.v | 8 ++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/vlib/encoding/html/escape.v b/vlib/encoding/html/escape.v index 5931adc4aee443..4c4ed9f7c6bcbd 100644 --- a/vlib/encoding/html/escape.v +++ b/vlib/encoding/html/escape.v @@ -5,15 +5,20 @@ pub struct EscapeConfig { quote bool = true } +const ( + html_replacement_table = ['&', '&', '<', '<', '>', '>'] + html_quote_replacement_table = ['"', '"', "'", '''] // `'"'` is shorter than `'"'` +) + // escape converts special characters in the input, specifically "<", ">", and "&" // to HTML-safe sequences. If `quote` is set to true (which is default), quotes in // HTML will also be translated. Both double and single quotes will be affected. // **Note:** escape() supports funky accents by doing nothing about them. V's UTF-8 // support through `string` is robust enough to deal with these cases. pub fn escape(input string, config EscapeConfig) string { - tag_free_input := input.replace_each(['&', '&', '<', '<', '>', '>']) + tag_free_input := input.replace_each(html.html_replacement_table) return if config.quote { - tag_free_input.replace_each(['"', '"', "'", ''']) + tag_free_input.replace_each(html.html_quote_replacement_table) } else { tag_free_input } diff --git a/vlib/encoding/html/escape_test.v b/vlib/encoding/html/escape_test.v index 2b8ffbe13c144b..da0cb50af9ff76 100644 --- a/vlib/encoding/html/escape_test.v +++ b/vlib/encoding/html/escape_test.v @@ -5,15 +5,15 @@ fn test_escape_html() { assert html.escape('No change') == 'No change' assert html.escape('Bold text') == '<b>Bold text</b>' assert html.escape('') == '<img />' - assert html.escape("' onmouseover='alert(1)'") == '' onmouseover='alert(1)'' - assert html.escape("link") == '<a href='http://www.example.com'>link</a>' - assert html.escape("") == '<script>alert('hello');</script>' + assert html.escape("' onmouseover='alert(1)'") == '' onmouseover='alert(1)'' + assert html.escape("link") == '<a href='http://www.example.com'>link</a>' + assert html.escape("") == '<script>alert('hello');</script>' // Cases obtained from: // https://github.com/apache/commons-lang/blob/master/src/test/java/org/apache/commons/lang3/StringEscapeUtilsTest.java assert html.escape('plain text') == 'plain text' assert html.escape('') == '' assert html.escape('bread & butter') == 'bread & butter' - assert html.escape('"bread" & butter') == '"bread" & butter' + assert html.escape('"bread" & butter') == '"bread" & butter' assert html.escape('greater than >') == 'greater than >' assert html.escape('< less than') == '< less than' // Leave accents as-is