Skip to content

Commit 7275d27

Browse files
author
David Heinemeier Hansson
committed
Fixed JSON encoding to use quoted keys according to the JSON standard (closes rails#8762) [choonkat/chuyeow]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7697 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
1 parent 66d05f5 commit 7275d27

File tree

7 files changed

+11
-52
lines changed

7 files changed

+11
-52
lines changed

actionpack/test/controller/render_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,19 @@ def test_do_with_render_text
209209

210210
def test_do_with_render_json
211211
get :render_json_hello_world
212-
assert_equal '{hello: "world"}', @response.body
212+
assert_equal '{"hello": "world"}', @response.body
213213
assert_equal 'application/json', @response.content_type
214214
end
215215

216216
def test_do_with_render_json_with_callback
217217
get :render_json_hello_world_with_callback
218-
assert_equal 'alert({hello: "world"})', @response.body
218+
assert_equal 'alert({"hello": "world"})', @response.body
219219
assert_equal 'application/json', @response.content_type
220220
end
221221

222222
def test_do_with_render_symbol_json
223223
get :render_symbol_json
224-
assert_equal '{hello: "world"}', @response.body
224+
assert_equal '{"hello": "world"}', @response.body
225225
assert_equal 'application/json', @response.content_type
226226
end
227227

activerecord/test/json_serialization_test.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88

99
class JsonSerializationTest < Test::Unit::TestCase
1010
def setup
11-
# Quote all keys (so that we can test against strictly valid JSON).
12-
ActiveSupport::JSON.unquote_hash_key_identifiers = false
13-
1411
@contact = Contact.new(
1512
:name => 'Konata Izumi',
1613
:age => 16,
@@ -70,8 +67,6 @@ class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
7067
fixtures :authors, :posts, :comments, :tags, :taggings
7168

7269
def setup
73-
ActiveSupport::JSON.unquote_hash_key_identifiers = false
74-
7570
@david = authors(:david)
7671
end
7772

activesupport/CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
*2.0.0 [Preview Release]* (September 29th, 2007)
22

3+
* Fixed JSON encoding to use quoted keys according to the JSON standard #8762 [choonkat/chuyeow]
4+
35
* Alias Object#send to send! for Ruby 1.9 forward compatibility. [Jeremy Kemper]
46

57
* Backport Object#instance_variable_defined? for Ruby < 1.8.6. [Jeremy Kemper]

activesupport/lib/active_support/json/encoders/hash.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ class Hash
22
def to_json #:nodoc:
33
returning result = '{' do
44
result << map do |key, value|
5-
key = ActiveSupport::JSON::Variable.new(key.to_s) if
6-
ActiveSupport::JSON.can_unquote_identifier?(key)
75
"#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(value)}"
86
end * ', '
97
result << '}'

activesupport/lib/active_support/json/encoding.rb

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010

1111
module ActiveSupport
1212
module JSON
13-
# When +true+, Hash#to_json will omit quoting string or symbol keys
14-
# if the keys are valid JavaScript identifiers. Note that this is
15-
# technically improper JSON (all object keys must be quoted), so if
16-
# you need strict JSON compliance, set this option to +false+.
17-
mattr_accessor :unquote_hash_key_identifiers
18-
@@unquote_hash_key_identifiers = true
19-
2013
class CircularReferenceError < StandardError
2114
end
2215

@@ -30,11 +23,6 @@ def encode(value)
3023
end
3124
end
3225

33-
def can_unquote_identifier?(key) #:nodoc:
34-
unquote_hash_key_identifiers &&
35-
ActiveSupport::JSON.valid_identifier?(key)
36-
end
37-
3826
protected
3927
def raise_on_circular_reference(value) #:nodoc:
4028
stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []

activesupport/lib/active_support/json/variable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ActiveSupport
22
module JSON
3-
# A string that returns itself as as its JSON-encoded form.
3+
# A string that returns itself as its JSON-encoded form.
44
class Variable < String
55
def to_json
66
self

activesupport/test/json/encoding_test.rb

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,12 @@ def initialize(a, b)
4141
end
4242
end
4343

44-
def setup
45-
unquote(false)
46-
end
47-
48-
def teardown
49-
unquote(true)
50-
end
51-
5244
def test_hash_encoding
5345
assert_equal %({\"a\": \"b\"}), { :a => :b }.to_json
5446
assert_equal %({\"a\": 1}), { 'a' => 1 }.to_json
5547
assert_equal %({\"a\": [1, 2]}), { 'a' => [1,2] }.to_json
56-
57-
sorted_json =
58-
'{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
48+
49+
sorted_json = '{' + {:a => :b, :c => :d}.to_json[1..-2].split(', ').sort.join(', ') + '}'
5950
assert_equal %({\"a\": \"b\", \"c\": \"d\"}), sorted_json
6051
end
6152

@@ -72,29 +63,14 @@ def test_exception_raised_when_encoding_circular_reference
7263
a << a
7364
assert_raises(ActiveSupport::JSON::CircularReferenceError) { a.to_json }
7465
end
75-
76-
def test_unquote_hash_key_identifiers
66+
67+
def test_hash_key_identifiers_are_always_quoted
7768
values = {0 => 0, 1 => 1, :_ => :_, "$" => "$", "a" => "a", :A => :A, :A0 => :A0, "A0B" => "A0B"}
7869
assert_equal %w( "$" "A" "A0" "A0B" "_" "a" 0 1 ), object_keys(values.to_json)
79-
unquote(true) { assert_equal %w( $ 0 1 A A0 A0B _ a ), object_keys(values.to_json) }
8070
end
81-
82-
def test_unquote_hash_key_identifiers_ignores_javascript_reserved_words
83-
values = {"hello" => "world", "this" => "that", "with" => "foo"}
84-
unquote(true) { assert_equal %w( "this" "with" hello ), object_keys(values.to_json) }
85-
end
86-
71+
8772
protected
88-
def unquote(value)
89-
previous_value = ActiveSupport::JSON.unquote_hash_key_identifiers
90-
ActiveSupport::JSON.unquote_hash_key_identifiers = value
91-
yield if block_given?
92-
ensure
93-
ActiveSupport::JSON.unquote_hash_key_identifiers = previous_value if block_given?
94-
end
95-
9673
def object_keys(json_object)
9774
json_object[1..-2].scan(/([^{}:,\s]+):/).flatten.sort
9875
end
99-
10076
end

0 commit comments

Comments
 (0)