diff options
-rw-r--r-- | actionview/CHANGELOG.md | 3 | ||||
-rw-r--r-- | actionview/test/template/erb_util_test.rb | 3 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/string/output_safety.rb | 12 |
3 files changed, 12 insertions, 6 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 65d045d1f7..9e58c193b1 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,4 +1,7 @@ * Fixed a long-standing bug in `json_escape` that causes quotation marks to be stripped. + This method also escapes the \u2028 and \u2029 unicode newline characters which are + treated as \n in JavaScript. This matches the behaviour of the AS::JSON encoder. (The + original change in the encoder was introduced in #10534.) *Godfrey Chan* diff --git a/actionview/test/template/erb_util_test.rb b/actionview/test/template/erb_util_test.rb index 62067ad097..9bacbba908 100644 --- a/actionview/test/template/erb_util_test.rb +++ b/actionview/test/template/erb_util_test.rb @@ -33,7 +33,8 @@ class ErbUtilTest < ActiveSupport::TestCase ['"&"', '"\u0026"'], ['"</script>"', '"\u003c/script\u003e"'], ['["</script>"]', '["\u003c/script\u003e"]'], - ['{"name":"</script>"}', '{"name":"\u003c/script\u003e"}'] + ['{"name":"</script>"}', '{"name":"\u003c/script\u003e"}'], + [%({"name":"d\u2028h\u2029h"}), '{"name":"d\u2028h\u2029h"}'] ] def test_html_escape diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 0e07e5952f..1d23998b88 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -4,9 +4,9 @@ require 'active_support/core_ext/kernel/singleton_class' class ERB module Util HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } - JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c' } + JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' } HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/ - JSON_ESCAPE_REGEXP = /[&><]/ + JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u # A utility method for escaping HTML tag characters. # This method is also aliased as <tt>h</tt>. @@ -50,9 +50,11 @@ class ERB # A utility method for escaping HTML entities in JSON strings. Specifically, the # &, > and < characters are replaced with their equivilant unicode escaped form - - # \u0026, \u003e, and \u003c. These sequences has identical meaning as the original - # characters inside the context of a JSON string, so assuming the input is a valid - # and well-formed JSON value, the output will have equivilant meaning when parsed: + # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also + # escaped as then are treated as newline characters in some JavaScript engines. + # These sequences has identical meaning as the original characters inside the + # context of a JSON string, so assuming the input is a valid and well-formed + # JSON value, the output will have equivilant meaning when parsed: # # json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"}) # # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}" |