json 1.8.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +9 -11
- data/{CHANGES → CHANGES.md} +186 -90
- data/Gemfile +10 -6
- data/{COPYING-json-jruby → LICENSE} +5 -6
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/{README.rdoc → README.md} +185 -134
- data/Rakefile +41 -40
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +142 -101
- data/ext/json/ext/generator/generator.h +7 -2
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +383 -463
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +141 -184
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/ByteListTranscoder.java +1 -2
- data/java/src/json/ext/Generator.java +44 -22
- data/java/src/json/ext/GeneratorMethods.java +1 -2
- data/java/src/json/ext/GeneratorService.java +1 -2
- data/java/src/json/ext/GeneratorState.java +3 -56
- data/java/src/json/ext/OptionsReader.java +2 -3
- data/java/src/json/ext/Parser.java +132 -415
- data/java/src/json/ext/Parser.rl +48 -124
- data/java/src/json/ext/ParserService.java +1 -2
- data/java/src/json/ext/RuntimeInfo.java +1 -6
- data/java/src/json/ext/StringDecoder.java +1 -2
- data/java/src/json/ext/StringEncoder.java +5 -0
- data/java/src/json/ext/Utils.java +1 -2
- data/json-java.gemspec +16 -2
- data/json.gemspec +0 -0
- data/json_pure.gemspec +24 -26
- data/lib/json/add/bigdecimal.rb +3 -2
- data/lib/json/add/complex.rb +4 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +3 -3
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +3 -2
- data/lib/json/add/regexp.rb +3 -3
- data/lib/json/add/set.rb +29 -0
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -1
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +26 -54
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure/generator.rb +63 -126
- data/lib/json/pure/parser.rb +41 -81
- data/lib/json/pure.rb +2 -8
- data/lib/json/version.rb +2 -1
- data/lib/json.rb +1 -0
- data/references/rfc7159.txt +899 -0
- data/tests/fixtures/obsolete_fail1.json +1 -0
- data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
- data/tests/json_common_interface_test.rb +126 -0
- data/tests/json_encoding_test.rb +107 -0
- data/tests/json_ext_parser_test.rb +15 -0
- data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
- data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +472 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +6 -0
- data/tools/diff.sh +18 -0
- data/tools/fuzz.rb +1 -9
- metadata +30 -47
- data/COPYING +0 -58
- data/GPL +0 -340
- data/TODO +0 -1
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/tests/fixtures/fail1.json +0 -1
- data/tests/test_json.rb +0 -553
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
|
+
# frozen_string_literal: false
|
3
4
|
|
4
|
-
require '
|
5
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
5
|
+
require 'test_helper'
|
6
6
|
|
7
|
-
class
|
7
|
+
class JSONGeneratorTest < Test::Unit::TestCase
|
8
8
|
include JSON
|
9
9
|
|
10
10
|
def setup
|
@@ -40,25 +40,63 @@ class TestJSONGenerate < Test::Unit::TestCase
|
|
40
40
|
EOT
|
41
41
|
end
|
42
42
|
|
43
|
+
def silence
|
44
|
+
v = $VERBOSE
|
45
|
+
$VERBOSE = nil
|
46
|
+
yield
|
47
|
+
ensure
|
48
|
+
$VERBOSE = v
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_remove_const_segv
|
52
|
+
return if RUBY_ENGINE == 'jruby'
|
53
|
+
stress = GC.stress
|
54
|
+
const = JSON::SAFE_STATE_PROTOTYPE.dup
|
55
|
+
|
56
|
+
bignum_too_long_to_embed_as_string = 1234567890123456789012345
|
57
|
+
expect = bignum_too_long_to_embed_as_string.to_s
|
58
|
+
GC.stress = true
|
59
|
+
|
60
|
+
10.times do |i|
|
61
|
+
tmp = bignum_too_long_to_embed_as_string.to_json
|
62
|
+
raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
|
63
|
+
end
|
64
|
+
|
65
|
+
silence do
|
66
|
+
JSON.const_set :SAFE_STATE_PROTOTYPE, nil
|
67
|
+
end
|
68
|
+
|
69
|
+
10.times do |i|
|
70
|
+
assert_raise TypeError do
|
71
|
+
bignum_too_long_to_embed_as_string.to_json
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ensure
|
75
|
+
GC.stress = stress
|
76
|
+
silence do
|
77
|
+
JSON.const_set :SAFE_STATE_PROTOTYPE, const
|
78
|
+
end
|
79
|
+
end if JSON.const_defined?("Ext")
|
80
|
+
|
43
81
|
def test_generate
|
44
82
|
json = generate(@hash)
|
45
|
-
assert_equal(
|
83
|
+
assert_equal(parse(@json2), parse(json))
|
46
84
|
json = JSON[@hash]
|
47
|
-
assert_equal(
|
85
|
+
assert_equal(parse(@json2), parse(json))
|
48
86
|
parsed_json = parse(json)
|
49
87
|
assert_equal(@hash, parsed_json)
|
50
88
|
json = generate({1=>2})
|
51
89
|
assert_equal('{"1":2}', json)
|
52
90
|
parsed_json = parse(json)
|
53
91
|
assert_equal({"1"=>2}, parsed_json)
|
54
|
-
|
55
|
-
assert_equal '666', generate(666, :quirks_mode => true)
|
92
|
+
assert_equal '666', generate(666)
|
56
93
|
end
|
57
94
|
|
58
95
|
def test_generate_pretty
|
59
96
|
json = pretty_generate(@hash)
|
60
|
-
# hashes aren't (insertion) ordered on every ruby implementation
|
61
|
-
assert_equal(
|
97
|
+
# hashes aren't (insertion) ordered on every ruby implementation
|
98
|
+
# assert_equal(@json3, json)
|
99
|
+
assert_equal(parse(@json3), parse(json))
|
62
100
|
parsed_json = parse(json)
|
63
101
|
assert_equal(@hash, parsed_json)
|
64
102
|
json = pretty_generate({1=>2})
|
@@ -69,8 +107,7 @@ EOT
|
|
69
107
|
EOT
|
70
108
|
parsed_json = parse(json)
|
71
109
|
assert_equal({"1"=>2}, parsed_json)
|
72
|
-
|
73
|
-
assert_equal '666', pretty_generate(666, :quirks_mode => true)
|
110
|
+
assert_equal '666', pretty_generate(666)
|
74
111
|
end
|
75
112
|
|
76
113
|
def test_generate_custom
|
@@ -88,30 +125,26 @@ EOT
|
|
88
125
|
|
89
126
|
def test_fast_generate
|
90
127
|
json = fast_generate(@hash)
|
91
|
-
assert_equal(
|
128
|
+
assert_equal(parse(@json2), parse(json))
|
92
129
|
parsed_json = parse(json)
|
93
130
|
assert_equal(@hash, parsed_json)
|
94
131
|
json = fast_generate({1=>2})
|
95
132
|
assert_equal('{"1":2}', json)
|
96
133
|
parsed_json = parse(json)
|
97
134
|
assert_equal({"1"=>2}, parsed_json)
|
98
|
-
|
99
|
-
assert_equal '666', fast_generate(666, :quirks_mode => true)
|
135
|
+
assert_equal '666', fast_generate(666)
|
100
136
|
end
|
101
137
|
|
102
138
|
def test_own_state
|
103
139
|
state = State.new
|
104
140
|
json = generate(@hash, state)
|
105
|
-
assert_equal(
|
141
|
+
assert_equal(parse(@json2), parse(json))
|
106
142
|
parsed_json = parse(json)
|
107
143
|
assert_equal(@hash, parsed_json)
|
108
144
|
json = generate({1=>2}, state)
|
109
145
|
assert_equal('{"1":2}', json)
|
110
146
|
parsed_json = parse(json)
|
111
147
|
assert_equal({"1"=>2}, parsed_json)
|
112
|
-
assert_raise(GeneratorError) { generate(666, state) }
|
113
|
-
state.quirks_mode = true
|
114
|
-
assert state.quirks_mode?
|
115
148
|
assert_equal '666', generate(666, state)
|
116
149
|
end
|
117
150
|
|
@@ -123,12 +156,12 @@ EOT
|
|
123
156
|
assert s[:check_circular?]
|
124
157
|
h = { 1=>2 }
|
125
158
|
h[3] = h
|
126
|
-
|
127
|
-
|
159
|
+
assert_raise(JSON::NestingError) { generate(h) }
|
160
|
+
assert_raise(JSON::NestingError) { generate(h, s) }
|
128
161
|
s = JSON.state.new
|
129
162
|
a = [ 1, 2 ]
|
130
163
|
a << a
|
131
|
-
|
164
|
+
assert_raise(JSON::NestingError) { generate(a, s) }
|
132
165
|
assert s.check_circular?
|
133
166
|
assert s[:check_circular?]
|
134
167
|
end
|
@@ -140,7 +173,6 @@ EOT
|
|
140
173
|
:array_nl => "\n",
|
141
174
|
:ascii_only => false,
|
142
175
|
:buffer_initial_length => 1024,
|
143
|
-
:quirks_mode => false,
|
144
176
|
:depth => 0,
|
145
177
|
:indent => " ",
|
146
178
|
:max_nesting => 100,
|
@@ -157,7 +189,6 @@ EOT
|
|
157
189
|
:array_nl => "",
|
158
190
|
:ascii_only => false,
|
159
191
|
:buffer_initial_length => 1024,
|
160
|
-
:quirks_mode => false,
|
161
192
|
:depth => 0,
|
162
193
|
:indent => "",
|
163
194
|
:max_nesting => 100,
|
@@ -174,7 +205,6 @@ EOT
|
|
174
205
|
:array_nl => "",
|
175
206
|
:ascii_only => false,
|
176
207
|
:buffer_initial_length => 1024,
|
177
|
-
:quirks_mode => false,
|
178
208
|
:depth => 0,
|
179
209
|
:indent => "",
|
180
210
|
:max_nesting => 0,
|
@@ -185,34 +215,34 @@ EOT
|
|
185
215
|
end
|
186
216
|
|
187
217
|
def test_allow_nan
|
188
|
-
|
218
|
+
assert_raise(GeneratorError) { generate([JSON::NaN]) }
|
189
219
|
assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
|
190
|
-
|
191
|
-
|
220
|
+
assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
|
221
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
|
192
222
|
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
|
193
|
-
|
223
|
+
assert_raise(GeneratorError) { generate([JSON::Infinity]) }
|
194
224
|
assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
|
195
|
-
|
196
|
-
|
225
|
+
assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
|
226
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
|
197
227
|
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
|
198
|
-
|
228
|
+
assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
|
199
229
|
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
|
200
|
-
|
201
|
-
|
230
|
+
assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
|
231
|
+
assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
|
202
232
|
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
|
203
233
|
end
|
204
234
|
|
205
235
|
def test_depth
|
206
236
|
ary = []; ary << ary
|
207
237
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
208
|
-
|
238
|
+
assert_raise(JSON::NestingError) { generate(ary) }
|
209
239
|
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
|
210
240
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
211
|
-
|
241
|
+
assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
|
212
242
|
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
|
213
243
|
s = JSON.state.new
|
214
244
|
assert_equal 0, s.depth
|
215
|
-
|
245
|
+
assert_raise(JSON::NestingError) { ary.to_json(s) }
|
216
246
|
assert_equal 100, s.depth
|
217
247
|
end
|
218
248
|
|
@@ -285,12 +315,13 @@ EOT
|
|
285
315
|
if defined?(JSON::Ext::Generator)
|
286
316
|
def test_broken_bignum # [ruby-core:38867]
|
287
317
|
pid = fork do
|
288
|
-
|
318
|
+
x = 1 << 64
|
319
|
+
x.class.class_eval do
|
289
320
|
def to_s
|
290
321
|
end
|
291
322
|
end
|
292
323
|
begin
|
293
|
-
JSON::Ext::Generator::State.new.generate(
|
324
|
+
JSON::Ext::Generator::State.new.generate(x)
|
294
325
|
exit 1
|
295
326
|
rescue TypeError
|
296
327
|
exit 0
|
@@ -331,7 +362,60 @@ EOT
|
|
331
362
|
|
332
363
|
def test_json_generate
|
333
364
|
assert_raise JSON::GeneratorError do
|
334
|
-
assert_equal true,
|
365
|
+
assert_equal true, generate(["\xea"])
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_nesting
|
370
|
+
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
|
371
|
+
too_deep_ary = eval too_deep
|
372
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary }
|
373
|
+
assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
|
374
|
+
ok = generate too_deep_ary, :max_nesting => 101
|
375
|
+
assert_equal too_deep, ok
|
376
|
+
ok = generate too_deep_ary, :max_nesting => nil
|
377
|
+
assert_equal too_deep, ok
|
378
|
+
ok = generate too_deep_ary, :max_nesting => false
|
379
|
+
assert_equal too_deep, ok
|
380
|
+
ok = generate too_deep_ary, :max_nesting => 0
|
381
|
+
assert_equal too_deep, ok
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_backslash
|
385
|
+
data = [ '\\.(?i:gif|jpe?g|png)$' ]
|
386
|
+
json = '["\\\\.(?i:gif|jpe?g|png)$"]'
|
387
|
+
assert_equal json, generate(data)
|
388
|
+
#
|
389
|
+
data = [ '\\"' ]
|
390
|
+
json = '["\\\\\""]'
|
391
|
+
assert_equal json, generate(data)
|
392
|
+
#
|
393
|
+
data = [ '/' ]
|
394
|
+
json = '["/"]'
|
395
|
+
assert_equal json, generate(data)
|
396
|
+
#
|
397
|
+
data = ['"']
|
398
|
+
json = '["\""]'
|
399
|
+
assert_equal json, generate(data)
|
400
|
+
#
|
401
|
+
data = ["'"]
|
402
|
+
json = '["\\\'"]'
|
403
|
+
assert_equal '["\'"]', generate(data)
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_string_subclass
|
407
|
+
s = Class.new(String) do
|
408
|
+
def to_s; self; end
|
409
|
+
undef to_json
|
410
|
+
end
|
411
|
+
assert_nothing_raised(SystemStackError) do
|
412
|
+
assert_equal '["foo"]', JSON.generate([s.new('foo')])
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
if defined?(Encoding)
|
417
|
+
def test_nonutf8_encoding
|
418
|
+
assert_equal("\"5\u{b0}\"", "5\xb0".force_encoding("iso-8859-1").to_json)
|
335
419
|
end
|
336
420
|
end
|
337
421
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#frozen_string_literal: false
|
2
|
+
require 'test_helper'
|
3
3
|
|
4
|
-
|
5
|
-
require File.join(File.dirname(__FILE__), 'setup_variant')
|
6
|
-
class TestJSONGenericObject < Test::Unit::TestCase
|
4
|
+
class JSONGenericObjectTest < Test::Unit::TestCase
|
7
5
|
include JSON
|
8
6
|
|
9
7
|
def setup
|
@@ -26,11 +24,20 @@ class TestJSONGenericObject < Test::Unit::TestCase
|
|
26
24
|
end
|
27
25
|
|
28
26
|
def test_parse_json
|
29
|
-
assert_kind_of Hash,
|
27
|
+
assert_kind_of Hash,
|
28
|
+
JSON(
|
29
|
+
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
30
|
+
:create_additions => true
|
31
|
+
)
|
30
32
|
switch_json_creatable do
|
31
|
-
assert_equal @go, l =
|
33
|
+
assert_equal @go, l =
|
34
|
+
JSON(
|
35
|
+
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
|
36
|
+
:create_additions => true
|
37
|
+
)
|
32
38
|
assert_equal 1, l.a
|
33
|
-
assert_equal @go,
|
39
|
+
assert_equal @go,
|
40
|
+
l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
|
34
41
|
assert_equal 1, l.a
|
35
42
|
assert_equal GenericObject[:a => GenericObject[:b => 2]],
|
36
43
|
l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
|