json 1.8.3 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +9 -12
  4. data/{CHANGES → CHANGES.md} +219 -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} +201 -134
  9. data/Rakefile +35 -113
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +255 -101
  13. data/ext/json/ext/generator/generator.h +12 -4
  14. data/ext/json/ext/parser/extconf.rb +28 -0
  15. data/ext/json/ext/parser/parser.c +410 -462
  16. data/ext/json/ext/parser/parser.h +5 -5
  17. data/ext/json/ext/parser/parser.rl +166 -181
  18. data/ext/json/extconf.rb +1 -1
  19. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  20. data/java/src/json/ext/Generator.java +39 -36
  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 +33 -56
  24. data/java/src/json/ext/OptionsReader.java +2 -3
  25. data/java/src/json/ext/Parser.java +146 -417
  26. data/java/src/json/ext/Parser.rl +62 -126
  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 +13 -2
  31. data/java/src/json/ext/Utils.java +1 -2
  32. data/json-java.gemspec +22 -7
  33. data/json.gemspec +0 -0
  34. data/json_pure.gemspec +22 -29
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -4
  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 -3
  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 +350 -152
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure/generator.rb +83 -126
  53. data/lib/json/pure/parser.rb +62 -84
  54. data/lib/json/pure.rb +2 -8
  55. data/lib/json/version.rb +2 -1
  56. data/lib/json.rb +550 -29
  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} +28 -25
  60. data/tests/json_common_interface_test.rb +169 -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} +13 -8
  64. data/tests/{test_json_generate.rb → json_generator_test.rb} +134 -39
  65. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  66. data/tests/json_parser_test.rb +497 -0
  67. data/tests/json_string_matching_test.rb +38 -0
  68. data/tests/test_helper.rb +17 -0
  69. data/tools/diff.sh +18 -0
  70. data/tools/fuzz.rb +1 -9
  71. metadata +47 -53
  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/setup_variant.rb +0 -11
  80. data/tests/test_json.rb +0 -553
  81. data/tests/test_json_encoding.rb +0 -65
  82. data/tests/test_json_string_matching.rb +0 -39
  83. 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,67 @@ 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
+ stress = GC.stress
53
+ const = JSON::SAFE_STATE_PROTOTYPE.dup
54
+
55
+ bignum_too_long_to_embed_as_string = 1234567890123456789012345
56
+ expect = bignum_too_long_to_embed_as_string.to_s
57
+ GC.stress = true
58
+
59
+ 10.times do |i|
60
+ tmp = bignum_too_long_to_embed_as_string.to_json
61
+ raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
62
+ end
63
+
64
+ silence do
65
+ JSON.const_set :SAFE_STATE_PROTOTYPE, nil
66
+ end
67
+
68
+ 10.times do |i|
69
+ assert_raise TypeError do
70
+ bignum_too_long_to_embed_as_string.to_json
71
+ end
72
+ end
73
+ ensure
74
+ GC.stress = stress
75
+ silence do
76
+ JSON.const_set :SAFE_STATE_PROTOTYPE, const
77
+ end
78
+ end if JSON.const_defined?("Ext") && RUBY_ENGINE != 'jruby'
79
+
43
80
  def test_generate
44
81
  json = generate(@hash)
45
- assert_equal(JSON.parse(@json2), JSON.parse(json))
82
+ assert_equal(parse(@json2), parse(json))
46
83
  json = JSON[@hash]
47
- assert_equal(JSON.parse(@json2), JSON.parse(json))
84
+ assert_equal(parse(@json2), parse(json))
48
85
  parsed_json = parse(json)
49
86
  assert_equal(@hash, parsed_json)
50
87
  json = generate({1=>2})
51
88
  assert_equal('{"1":2}', json)
52
89
  parsed_json = parse(json)
53
90
  assert_equal({"1"=>2}, parsed_json)
54
- assert_raise(GeneratorError) { generate(666) }
55
- assert_equal '666', generate(666, :quirks_mode => true)
91
+ assert_equal '666', generate(666)
56
92
  end
57
93
 
58
94
  def test_generate_pretty
95
+ json = pretty_generate({})
96
+ assert_equal(<<'EOT'.chomp, json)
97
+ {
98
+ }
99
+ EOT
59
100
  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))
101
+ # hashes aren't (insertion) ordered on every ruby implementation
102
+ # assert_equal(@json3, json)
103
+ assert_equal(parse(@json3), parse(json))
62
104
  parsed_json = parse(json)
63
105
  assert_equal(@hash, parsed_json)
64
106
  json = pretty_generate({1=>2})
@@ -69,8 +111,7 @@ EOT
69
111
  EOT
70
112
  parsed_json = parse(json)
71
113
  assert_equal({"1"=>2}, parsed_json)
72
- assert_raise(GeneratorError) { pretty_generate(666) }
73
- assert_equal '666', pretty_generate(666, :quirks_mode => true)
114
+ assert_equal '666', pretty_generate(666)
74
115
  end
75
116
 
76
117
  def test_generate_custom
@@ -88,30 +129,26 @@ EOT
88
129
 
89
130
  def test_fast_generate
90
131
  json = fast_generate(@hash)
91
- assert_equal(JSON.parse(@json2), JSON.parse(json))
132
+ assert_equal(parse(@json2), parse(json))
92
133
  parsed_json = parse(json)
93
134
  assert_equal(@hash, parsed_json)
94
135
  json = fast_generate({1=>2})
95
136
  assert_equal('{"1":2}', json)
96
137
  parsed_json = parse(json)
97
138
  assert_equal({"1"=>2}, parsed_json)
98
- assert_raise(GeneratorError) { fast_generate(666) }
99
- assert_equal '666', fast_generate(666, :quirks_mode => true)
139
+ assert_equal '666', fast_generate(666)
100
140
  end
101
141
 
102
142
  def test_own_state
103
143
  state = State.new
104
144
  json = generate(@hash, state)
105
- assert_equal(JSON.parse(@json2), JSON.parse(json))
145
+ assert_equal(parse(@json2), parse(json))
106
146
  parsed_json = parse(json)
107
147
  assert_equal(@hash, parsed_json)
108
148
  json = generate({1=>2}, state)
109
149
  assert_equal('{"1":2}', json)
110
150
  parsed_json = parse(json)
111
151
  assert_equal({"1"=>2}, parsed_json)
112
- assert_raise(GeneratorError) { generate(666, state) }
113
- state.quirks_mode = true
114
- assert state.quirks_mode?
115
152
  assert_equal '666', generate(666, state)
116
153
  end
117
154
 
@@ -123,12 +160,12 @@ EOT
123
160
  assert s[:check_circular?]
124
161
  h = { 1=>2 }
125
162
  h[3] = h
126
- assert_raises(JSON::NestingError) { generate(h) }
127
- assert_raises(JSON::NestingError) { generate(h, s) }
163
+ assert_raise(JSON::NestingError) { generate(h) }
164
+ assert_raise(JSON::NestingError) { generate(h, s) }
128
165
  s = JSON.state.new
129
166
  a = [ 1, 2 ]
130
167
  a << a
131
- assert_raises(JSON::NestingError) { generate(a, s) }
168
+ assert_raise(JSON::NestingError) { generate(a, s) }
132
169
  assert s.check_circular?
133
170
  assert s[:check_circular?]
134
171
  end
@@ -140,8 +177,8 @@ EOT
140
177
  :array_nl => "\n",
141
178
  :ascii_only => false,
142
179
  :buffer_initial_length => 1024,
143
- :quirks_mode => false,
144
180
  :depth => 0,
181
+ :escape_slash => false,
145
182
  :indent => " ",
146
183
  :max_nesting => 100,
147
184
  :object_nl => "\n",
@@ -157,8 +194,8 @@ EOT
157
194
  :array_nl => "",
158
195
  :ascii_only => false,
159
196
  :buffer_initial_length => 1024,
160
- :quirks_mode => false,
161
197
  :depth => 0,
198
+ :escape_slash => false,
162
199
  :indent => "",
163
200
  :max_nesting => 100,
164
201
  :object_nl => "",
@@ -174,8 +211,8 @@ EOT
174
211
  :array_nl => "",
175
212
  :ascii_only => false,
176
213
  :buffer_initial_length => 1024,
177
- :quirks_mode => false,
178
214
  :depth => 0,
215
+ :escape_slash => false,
179
216
  :indent => "",
180
217
  :max_nesting => 0,
181
218
  :object_nl => "",
@@ -185,34 +222,34 @@ EOT
185
222
  end
186
223
 
187
224
  def test_allow_nan
188
- assert_raises(GeneratorError) { generate([JSON::NaN]) }
225
+ assert_raise(GeneratorError) { generate([JSON::NaN]) }
189
226
  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]) }
227
+ assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
228
+ assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
192
229
  assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
193
- assert_raises(GeneratorError) { generate([JSON::Infinity]) }
230
+ assert_raise(GeneratorError) { generate([JSON::Infinity]) }
194
231
  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]) }
232
+ assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
233
+ assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
197
234
  assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
198
- assert_raises(GeneratorError) { generate([JSON::MinusInfinity]) }
235
+ assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
199
236
  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]) }
237
+ assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
238
+ assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
202
239
  assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
203
240
  end
204
241
 
205
242
  def test_depth
206
243
  ary = []; ary << ary
207
244
  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
208
- assert_raises(JSON::NestingError) { JSON.generate(ary) }
245
+ assert_raise(JSON::NestingError) { generate(ary) }
209
246
  assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
210
247
  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
211
- assert_raises(JSON::NestingError) { JSON.pretty_generate(ary) }
248
+ assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
212
249
  assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
213
250
  s = JSON.state.new
214
251
  assert_equal 0, s.depth
215
- assert_raises(JSON::NestingError) { ary.to_json(s) }
252
+ assert_raise(JSON::NestingError) { ary.to_json(s) }
216
253
  assert_equal 100, s.depth
217
254
  end
218
255
 
@@ -285,12 +322,13 @@ EOT
285
322
  if defined?(JSON::Ext::Generator)
286
323
  def test_broken_bignum # [ruby-core:38867]
287
324
  pid = fork do
288
- Bignum.class_eval do
325
+ x = 1 << 64
326
+ x.class.class_eval do
289
327
  def to_s
290
328
  end
291
329
  end
292
330
  begin
293
- JSON::Ext::Generator::State.new.generate(1<<64)
331
+ JSON::Ext::Generator::State.new.generate(x)
294
332
  exit 1
295
333
  rescue TypeError
296
334
  exit 0
@@ -331,7 +369,64 @@ EOT
331
369
 
332
370
  def test_json_generate
333
371
  assert_raise JSON::GeneratorError do
334
- assert_equal true, JSON.generate(["\xea"])
372
+ assert_equal true, generate(["\xea"])
373
+ end
374
+ end
375
+
376
+ def test_nesting
377
+ too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
378
+ too_deep_ary = eval too_deep
379
+ assert_raise(JSON::NestingError) { generate too_deep_ary }
380
+ assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
381
+ ok = generate too_deep_ary, :max_nesting => 101
382
+ assert_equal too_deep, ok
383
+ ok = generate too_deep_ary, :max_nesting => nil
384
+ assert_equal too_deep, ok
385
+ ok = generate too_deep_ary, :max_nesting => false
386
+ assert_equal too_deep, ok
387
+ ok = generate too_deep_ary, :max_nesting => 0
388
+ assert_equal too_deep, ok
389
+ end
390
+
391
+ def test_backslash
392
+ data = [ '\\.(?i:gif|jpe?g|png)$' ]
393
+ json = '["\\\\.(?i:gif|jpe?g|png)$"]'
394
+ assert_equal json, generate(data)
395
+ #
396
+ data = [ '\\"' ]
397
+ json = '["\\\\\""]'
398
+ assert_equal json, generate(data)
399
+ #
400
+ data = [ '/' ]
401
+ json = '["/"]'
402
+ assert_equal json, generate(data)
403
+ #
404
+ data = [ '/' ]
405
+ json = '["\/"]'
406
+ assert_equal json, generate(data, :escape_slash => true)
407
+ #
408
+ data = ['"']
409
+ json = '["\""]'
410
+ assert_equal json, generate(data)
411
+ #
412
+ data = ["'"]
413
+ json = '["\\\'"]'
414
+ assert_equal '["\'"]', generate(data)
415
+ end
416
+
417
+ def test_string_subclass
418
+ s = Class.new(String) do
419
+ def to_s; self; end
420
+ undef to_json
421
+ end
422
+ assert_nothing_raised(SystemStackError) do
423
+ assert_equal '["foo"]', JSON.generate([s.new('foo')])
424
+ end
425
+ end
426
+
427
+ if defined?(Encoding)
428
+ def test_nonutf8_encoding
429
+ assert_equal("\"5\u{b0}\"", "5\xb0".force_encoding("iso-8859-1").to_json)
335
430
  end
336
431
  end
337
432
  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)