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:
parent
8b2a6014a2
commit
34c125d774
@ -1,5 +1,7 @@
|
|||||||
*SVN*
|
*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]
|
* 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
|
The intention is to use this to reduce the amount of monkeypatching / overriding that
|
||||||
|
@ -43,7 +43,7 @@ def convert_json_to_yaml(json) #:nodoc:
|
|||||||
end
|
end
|
||||||
|
|
||||||
if marks.empty?
|
if marks.empty?
|
||||||
json
|
json.gsub(/\\\//, '/')
|
||||||
else
|
else
|
||||||
# FIXME: multiple slow enumerations
|
# FIXME: multiple slow enumerations
|
||||||
output = ([0] + marks.map(&:succ)).
|
output = ([0] + marks.map(&:succ)).
|
||||||
@ -51,6 +51,7 @@ def convert_json_to_yaml(json) #:nodoc:
|
|||||||
map { |left, right| json[left..right] }.
|
map { |left, right| json[left..right] }.
|
||||||
join(" ")
|
join(" ")
|
||||||
times.each { |i| output[i-1] = ' ' }
|
times.each { |i| output[i-1] = ' ' }
|
||||||
|
output.gsub!(/\\\//, '/')
|
||||||
output
|
output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3,14 +3,15 @@ module JSON
|
|||||||
module Encoding
|
module Encoding
|
||||||
ESCAPED_CHARS = {
|
ESCAPED_CHARS = {
|
||||||
"\010" => '\b',
|
"\010" => '\b',
|
||||||
"\f" => '\f',
|
"\f" => '\f',
|
||||||
"\n" => '\n',
|
"\n" => '\n',
|
||||||
"\r" => '\r',
|
"\r" => '\r',
|
||||||
"\t" => '\t',
|
"\t" => '\t',
|
||||||
'"' => '\"',
|
'"' => '\"',
|
||||||
'\\' => '\\\\',
|
'\\' => '\\\\',
|
||||||
">" => '\076',
|
">" => '\076',
|
||||||
'<' => '\074'
|
'<' => '\074',
|
||||||
|
'/' => '\\/'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -18,7 +19,7 @@ module Encoding
|
|||||||
|
|
||||||
class String
|
class String
|
||||||
def to_json(options = nil) #:nodoc:
|
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]
|
ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
|
||||||
}.gsub(/([\xC0-\xDF][\x80-\xBF]|
|
}.gsub(/([\xC0-\xDF][\x80-\xBF]|
|
||||||
[\xE0-\xEF][\x80-\xBF]{2}|
|
[\xE0-\xEF][\x80-\xBF]{2}|
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
class TestJSONDecoding < Test::Unit::TestCase
|
class TestJSONDecoding < Test::Unit::TestCase
|
||||||
TESTS = {
|
TESTS = {
|
||||||
%({"returnTo":{"/categories":"/"}}) => {"returnTo" => {"/categories" => "/"}},
|
%q({"returnTo":{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
||||||
%({returnTo:{"/categories":"/"}}) => {"returnTo" => {"/categories" => "/"}},
|
%q({returnTo:{"\/categories":"\/"}}) => {"returnTo" => {"/categories" => "/"}},
|
||||||
%({"return\\"To\\":":{"/categories":"/"}}) => {"return\"To\":" => {"/categories" => "/"}},
|
%q({"return\\"To\\":":{"\/categories":"\/"}}) => {"return\"To\":" => {"/categories" => "/"}},
|
||||||
%({"returnTo":{"/categories":1}}) => {"returnTo" => {"/categories" => 1}},
|
%q({"returnTo":{"\/categories":1}}) => {"returnTo" => {"/categories" => 1}},
|
||||||
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
|
%({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]},
|
||||||
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
|
%({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]},
|
||||||
%({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
|
%({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"},
|
||||||
@ -23,11 +23,12 @@ class TestJSONDecoding < Test::Unit::TestCase
|
|||||||
%("\\"") => "\"",
|
%("\\"") => "\"",
|
||||||
%(null) => nil,
|
%(null) => nil,
|
||||||
%(true) => true,
|
%(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_nothing_raised do
|
||||||
assert_equal expected, ActiveSupport::JSON.decode(json)
|
assert_equal expected, ActiveSupport::JSON.decode(json)
|
||||||
end
|
end
|
||||||
@ -37,4 +38,4 @@ def test_json_decoding
|
|||||||
def test_failed_json_decoding
|
def test_failed_json_decoding
|
||||||
assert_raises(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
|
assert_raises(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -14,7 +14,8 @@ def initialize(a, b)
|
|||||||
[ 2.5, %(2.5) ]]
|
[ 2.5, %(2.5) ]]
|
||||||
|
|
||||||
StringTests = [[ 'this is the <string>', %("this is the \\074string\\076")],
|
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\"]) ],
|
ArrayTests = [[ ['a', 'b', 'c'], %([\"a\", \"b\", \"c\"]) ],
|
||||||
[ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]
|
[ [1, 'a', :b, nil, false], %([1, \"a\", \"b\", null, false]) ]]
|
||||||
|
Loading…
Reference in New Issue
Block a user