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.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -11
  4. data/{CHANGES → CHANGES.md} +186 -90
  5. data/Gemfile +10 -6
  6. data/{COPYING-json-jruby → LICENSE} +5 -6
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/{README.rdoc → README.md} +185 -134
  9. data/Rakefile +41 -40
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +142 -101
  13. data/ext/json/ext/generator/generator.h +7 -2
  14. data/ext/json/ext/parser/extconf.rb +3 -0
  15. data/ext/json/ext/parser/parser.c +383 -463
  16. data/ext/json/ext/parser/parser.h +4 -5
  17. data/ext/json/ext/parser/parser.rl +141 -184
  18. data/ext/json/extconf.rb +0 -1
  19. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  20. data/java/src/json/ext/Generator.java +44 -22
  21. data/java/src/json/ext/GeneratorMethods.java +1 -2
  22. data/java/src/json/ext/GeneratorService.java +1 -2
  23. data/java/src/json/ext/GeneratorState.java +3 -56
  24. data/java/src/json/ext/OptionsReader.java +2 -3
  25. data/java/src/json/ext/Parser.java +132 -415
  26. data/java/src/json/ext/Parser.rl +48 -124
  27. data/java/src/json/ext/ParserService.java +1 -2
  28. data/java/src/json/ext/RuntimeInfo.java +1 -6
  29. data/java/src/json/ext/StringDecoder.java +1 -2
  30. data/java/src/json/ext/StringEncoder.java +5 -0
  31. data/java/src/json/ext/Utils.java +1 -2
  32. data/json-java.gemspec +16 -2
  33. data/json.gemspec +0 -0
  34. data/json_pure.gemspec +24 -26
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -3
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -2
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +26 -54
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure/generator.rb +63 -126
  53. data/lib/json/pure/parser.rb +41 -81
  54. data/lib/json/pure.rb +2 -8
  55. data/lib/json/version.rb +2 -1
  56. data/lib/json.rb +1 -0
  57. data/references/rfc7159.txt +899 -0
  58. data/tests/fixtures/obsolete_fail1.json +1 -0
  59. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  60. data/tests/json_common_interface_test.rb +126 -0
  61. data/tests/json_encoding_test.rb +107 -0
  62. data/tests/json_ext_parser_test.rb +15 -0
  63. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  64. data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
  65. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  66. data/tests/json_parser_test.rb +472 -0
  67. data/tests/json_string_matching_test.rb +38 -0
  68. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  69. data/tools/diff.sh +18 -0
  70. data/tools/fuzz.rb +1 -9
  71. metadata +30 -47
  72. data/COPYING +0 -58
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/test_json.rb +0 -553
  80. data/tests/test_json_encoding.rb +0 -65
  81. data/tests/test_json_string_matching.rb +0 -39
  82. 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 'test/unit'
5
- require File.join(File.dirname(__FILE__), 'setup_variant')
5
+ require 'test_helper'
6
6
 
7
- class TestJSONGenerate < Test::Unit::TestCase
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(JSON.parse(@json2), JSON.parse(json))
83
+ assert_equal(parse(@json2), parse(json))
46
84
  json = JSON[@hash]
47
- assert_equal(JSON.parse(@json2), JSON.parse(json))
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
- assert_raise(GeneratorError) { generate(666) }
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 assert_equal(@json3, json)
61
- assert_equal(JSON.parse(@json3), JSON.parse(json))
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
- assert_raise(GeneratorError) { pretty_generate(666) }
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(JSON.parse(@json2), JSON.parse(json))
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
- assert_raise(GeneratorError) { fast_generate(666) }
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(JSON.parse(@json2), JSON.parse(json))
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
- assert_raises(JSON::NestingError) { generate(h) }
127
- assert_raises(JSON::NestingError) { generate(h, s) }
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
- assert_raises(JSON::NestingError) { generate(a, s) }
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
- assert_raises(GeneratorError) { generate([JSON::NaN]) }
218
+ assert_raise(GeneratorError) { generate([JSON::NaN]) }
189
219
  assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
190
- assert_raises(GeneratorError) { fast_generate([JSON::NaN]) }
191
- assert_raises(GeneratorError) { pretty_generate([JSON::NaN]) }
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
- assert_raises(GeneratorError) { generate([JSON::Infinity]) }
223
+ assert_raise(GeneratorError) { generate([JSON::Infinity]) }
194
224
  assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
195
- assert_raises(GeneratorError) { fast_generate([JSON::Infinity]) }
196
- assert_raises(GeneratorError) { pretty_generate([JSON::Infinity]) }
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
- assert_raises(GeneratorError) { generate([JSON::MinusInfinity]) }
228
+ assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
199
229
  assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
200
- assert_raises(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
201
- assert_raises(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
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
- assert_raises(JSON::NestingError) { JSON.generate(ary) }
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
- assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) }
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
- assert_raises(JSON::NestingError) { ary.to_json(s) }
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
- Bignum.class_eval do
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(1<<64)
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, JSON.generate(["\xea"])
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
- #!/usr/bin/env ruby
2
- # encoding: utf-8
1
+ #frozen_string_literal: false
2
+ require 'test_helper'
3
3
 
4
- require 'test/unit'
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, JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
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 = JSON('{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }', :create_additions => true)
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, l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
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)