Fix JSON encoding/decoding bugs dealing with /'s. Closes #9990 [Rick, theamazingrando]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8026 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Rick Olson
2007-10-26 03:22:02 +00:00
parent 8b2a6014a2
commit 34c125d774
5 changed files with 25 additions and 19 deletions

View File

@@ -1,5 +1,7 @@
*SVN*
* Fix JSON encoding/decoding bugs dealing with /'s. Closes #9990 [Rick, theamazingrando]
* Introduce a base class for all test cases used by rails applications. ActiveSupport::TestCase [Koz]
The intention is to use this to reduce the amount of monkeypatching / overriding that

View File

@@ -43,7 +43,7 @@ module ActiveSupport
end
if marks.empty?
json
json.gsub(/\\\//, '/')
else
# FIXME: multiple slow enumerations
output = ([0] + marks.map(&:succ)).
@@ -51,6 +51,7 @@ module ActiveSupport
map { |left, right| json[left..right] }.
join(" ")
times.each { |i| output[i-1] = ' ' }
output.gsub!(/\\\//, '/')
output
end
end

View File

@@ -3,14 +3,15 @@ module ActiveSupport
module Encoding
ESCAPED_CHARS = {
"\010" => '\b',
"\f" => '\f',
"\n" => '\n',
"\r" => '\r',
"\t" => '\t',
'"' => '\"',
'\\' => '\\\\',
">" => '\076',
'<' => '\074'
"\f" => '\f',
"\n" => '\n',
"\r" => '\r',
"\t" => '\t',
'"' => '\"',
'\\' => '\\\\',
">" => '\076',
'<' => '\074',
'/' => '\\/'
}
end
end
@@ -18,7 +19,7 @@ end
class String
def to_json(options = nil) #:nodoc:
'"' + gsub(/[\010\f\n\r\t"\\><]/) { |s|
'"' + gsub(/[\010\f\n\r\t"\\><\/]/) { |s|
ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
}.gsub(/([\xC0-\xDF][\x80-\xBF]|
[\xE0-\xEF][\x80-\xBF]{2}|

View File

@@ -2,10 +2,10 @@ require File.dirname(__FILE__) + '/../abstract_unit'
class TestJSONDecoding < Test::Unit::TestCase
TESTS = {
%({"returnTo":{"/categories":"/"}}) => {"returnTo" => {"/categories" => "/"}},
%({returnTo:{"/categories":"/"}}) => {"returnTo" => {"/categories" => "/"}},
%({"return\\"To\\":":{"/categories":"/"}}) => {"return\"To\":" => {"/categories" => "/"}},
%({"returnTo":{"/categories":1}}) => {"returnTo" => {"/categories" => 1}},
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
%q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
%({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
@@ -23,11 +23,12 @@ class TestJSONDecoding < Test::Unit::TestCase
%("\\"") => "\"",
%(null) => nil,
%(true) => true,
%(false) => false
%(false) => false,
%q("http:\/\/test.host\/posts\/1") => "http://test.host/posts/1"
}
def test_json_decoding
TESTS.each do |json, expected|
TESTS.each do |json, expected|
define_method :"test_json_decoding_#{json}" do
assert_nothing_raised do
assert_equal expected, ActiveSupport::JSON.decode(json)
end
@@ -37,4 +38,4 @@ class TestJSONDecoding < Test::Unit::TestCase
def test_failed_json_decoding
assert_raises(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
end
end
end

View File

@@ -14,7 +14,8 @@ class TestJSONEncoding < Test::Unit::TestCase
[ 2.5, %(2.5) ]]
StringTests = [[ 'this is the <string>', %("this is the \\074string\\076")],
[ 'a "string" with quotes', %("a \\"string\\" with quotes") ]]
[ 'a "string" with quotes', %("a \\"string\\" with quotes") ],
[ 'http://test.host/posts/1', %("http:\\/\\/test.host\\/posts\\/1")]]
ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ],
[ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]