From e853809d6b00930c3b20773ba453c4744a91126b Mon Sep 17 00:00:00 2001 From: Dwayne Litzenberger Date: Tue, 22 Dec 2009 15:17:55 -0500 Subject: [PATCH] Fix ActiveSupport::JSON encoding of control characters [\x00-\x1f] According to RFC 4627, only the following Unicode code points are allowed unescaped in JSON: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF However, ActiveSupport::JSON did not escape the range %x00-1f. This caused parse errors when trying to decode the resulting output. --- activesupport/lib/active_support/json/encoding.rb | 13 +++++++++++-- activesupport/test/json/encoding_test.rb | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index ffd2050..0fbf2fe 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -22,6 +22,15 @@ module ActiveSupport end ESCAPED_CHARS = { + "\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002', + "\x03" => '\u0003', "\x04" => '\u0004', "\x05" => '\u0005', + "\x06" => '\u0006', "\x07" => '\u0007', "\x0B" => '\u000B', + "\x0E" => '\u000E', "\x0F" => '\u000F', "\x10" => '\u0010', + "\x11" => '\u0011', "\x12" => '\u0012', "\x13" => '\u0013', + "\x14" => '\u0014', "\x15" => '\u0015', "\x16" => '\u0016', + "\x17" => '\u0017', "\x18" => '\u0018', "\x19" => '\u0019', + "\x1A" => '\u001A', "\x1B" => '\u001B', "\x1C" => '\u001C', + "\x1D" => '\u001D', "\x1E" => '\u001E', "\x1F" => '\u001F', "\010" => '\b', "\f" => '\f', "\n" => '\n', @@ -43,9 +52,9 @@ module ActiveSupport def escape_html_entities_in_json=(value) self.escape_regex = \ if @escape_html_entities_in_json = value - /[\010\f\n\r\t"\\><&]/ + /[\x00-\x1F"\\><&]/ else - /[\010\f\n\r\t"\\]/ + /[\x00-\x1F"\\]/ end end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index ab8e4e8..47b2ba2 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -22,7 +22,9 @@ class TestJSONEncoding < Test::Unit::TestCase StringTests = [[ 'this is the ', %("this is the \\u003Cstring\\u003E")], [ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ], - [ 'http://test.host/posts/1', %("http://test.host/posts/1")]] + [ 'http://test.host/posts/1', %("http://test.host/posts/1")], + [ "Control characters: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + %("Control characters: \\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F") ]] ArrayTests = [[ ['a', 'b', 'c'], %([\"a\",\"b\",\"c\"]) ], [ [1, 'a', :b, nil, false], %([1,\"a\",\"b\",null,false]) ]] -- 1.6.5.2