json 2.10.2 → 2.19.9

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.
@@ -8,20 +8,8 @@ module JSON
8
8
  #
9
9
  # Instantiates a new State object, configured by _opts_.
10
10
  #
11
- # _opts_ can have the following keys:
12
- #
13
- # * *indent*: a string used to indent levels (default: ''),
14
- # * *space*: a string that is put after, a : or , delimiter (default: ''),
15
- # * *space_before*: a string that is put before a : pair delimiter (default: ''),
16
- # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
17
- # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
18
- # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
19
- # generated, otherwise an exception is thrown, if these values are
20
- # encountered. This options defaults to false.
21
- # * *ascii_only*: true if only ASCII characters should be generated. This
22
- # option defaults to false.
23
- # * *buffer_initial_length*: sets the initial length of the generator's
24
- # internal buffer.
11
+ # Argument +opts+, if given, contains a \Hash of options for the generation.
12
+ # See {Generating Options}[rdoc-ref:JSON@Generating+Options].
25
13
  def initialize(opts = nil)
26
14
  if opts && !opts.empty?
27
15
  configure(opts)
@@ -68,6 +56,11 @@ module JSON
68
56
  buffer_initial_length: buffer_initial_length,
69
57
  }
70
58
 
59
+ allow_duplicate_key = allow_duplicate_key?
60
+ unless allow_duplicate_key.nil?
61
+ result[:allow_duplicate_key] = allow_duplicate_key
62
+ end
63
+
71
64
  instance_variables.each do |iv|
72
65
  iv = iv.to_s[1..-1]
73
66
  result[iv.to_sym] = self[iv]
@@ -82,6 +75,8 @@ module JSON
82
75
  #
83
76
  # Returns the value returned by method +name+.
84
77
  def [](name)
78
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
79
+
85
80
  if respond_to?(name)
86
81
  __send__(name)
87
82
  else
@@ -94,6 +89,8 @@ module JSON
94
89
  #
95
90
  # Sets the attribute name to value.
96
91
  def []=(name, value)
92
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
93
+
97
94
  if respond_to?(name_writer = "#{name}=")
98
95
  __send__ name_writer, value
99
96
  else
data/lib/json/ext.rb CHANGED
@@ -34,12 +34,12 @@ module JSON
34
34
 
35
35
  if RUBY_ENGINE == 'truffleruby'
36
36
  require 'json/truffle_ruby/generator'
37
- JSON.generator = ::JSON::TruffleRuby::Generator
37
+ JSON.generator = JSON::TruffleRuby::Generator
38
38
  else
39
39
  require 'json/ext/generator'
40
40
  JSON.generator = Generator
41
41
  end
42
42
  end
43
43
 
44
- JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
44
+ JSON_LOADED = true unless defined?(JSON::JSON_LOADED)
45
45
  end
@@ -52,14 +52,6 @@ module JSON
52
52
  table
53
53
  end
54
54
 
55
- def [](name)
56
- __send__(name)
57
- end unless method_defined?(:[])
58
-
59
- def []=(name, value)
60
- __send__("#{name}=", value)
61
- end unless method_defined?(:[]=)
62
-
63
55
  def |(other)
64
56
  self.class[other.to_hash.merge(to_hash)]
65
57
  end
@@ -47,6 +47,19 @@ module JSON
47
47
 
48
48
  SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
49
49
 
50
+ def self.native_type?(value) # :nodoc:
51
+ (false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
52
+ end
53
+
54
+ def self.native_key?(key) # :nodoc:
55
+ (Symbol === key || String === key)
56
+ end
57
+
58
+ def self.valid_encoding?(string) # :nodoc:
59
+ return false unless string.encoding == ::Encoding::UTF_8 || string.encoding == ::Encoding::US_ASCII
60
+ string.is_a?(Symbol) || string.valid_encoding?
61
+ end
62
+
50
63
  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
51
64
  # UTF16 big endian characters as \u????, and return it.
52
65
  def self.utf8_to_json(string, script_safe = false) # :nodoc:
@@ -117,7 +130,7 @@ module JSON
117
130
  return new(opts.to_h)
118
131
  end
119
132
  end
120
- SAFE_STATE_PROTOTYPE.dup
133
+ new
121
134
  end
122
135
 
123
136
  # Instantiates a new State object, configured by _opts_.
@@ -198,13 +211,20 @@ module JSON
198
211
 
199
212
  # This integer returns the current depth data structure nesting in the
200
213
  # generated JSON.
201
- attr_accessor :depth
214
+ attr_reader :depth
215
+
216
+ def depth=(depth)
217
+ if depth.negative?
218
+ raise ArgumentError, "depth must be >= 0 (got #{depth})"
219
+ end
220
+ @depth = depth
221
+ end
202
222
 
203
223
  def check_max_nesting # :nodoc:
204
224
  return if @max_nesting.zero?
205
225
  current_nesting = depth + 1
206
226
  current_nesting > @max_nesting and
207
- raise NestingError, "nesting of #{current_nesting} is too deep"
227
+ raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
208
228
  end
209
229
 
210
230
  # Returns true, if circular data structures are checked,
@@ -247,6 +267,11 @@ module JSON
247
267
  else
248
268
  raise TypeError, "can't convert #{opts.class} into Hash"
249
269
  end
270
+
271
+ if opts[:depth]&.negative?
272
+ raise ArgumentError, "depth must be >= 0 (got #{opts[:depth]})"
273
+ end
274
+
250
275
  opts.each do |key, value|
251
276
  instance_variable_set "@#{key}", value
252
277
  end
@@ -271,11 +296,20 @@ module JSON
271
296
  false
272
297
  end
273
298
 
299
+ if opts.key?(:allow_duplicate_key)
300
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
301
+ else
302
+ @allow_duplicate_key = nil # nil is deprecation
303
+ end
304
+
274
305
  @strict = !!opts[:strict] if opts.key?(:strict)
275
306
 
276
307
  if !opts.key?(:max_nesting) # defaults to 100
277
308
  @max_nesting = 100
278
309
  elsif opts[:max_nesting]
310
+ unless opts[:max_nesting].is_a?(Integer)
311
+ raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
312
+ end
279
313
  @max_nesting = opts[:max_nesting]
280
314
  else
281
315
  @max_nesting = 0
@@ -284,14 +318,23 @@ module JSON
284
318
  end
285
319
  alias merge configure
286
320
 
321
+ def allow_duplicate_key? # :nodoc:
322
+ @allow_duplicate_key
323
+ end
324
+
287
325
  # Returns the configuration instance variables as a hash, that can be
288
326
  # passed to the configure method.
289
327
  def to_h
290
328
  result = {}
291
329
  instance_variables.each do |iv|
292
- iv = iv.to_s[1..-1]
293
- result[iv.to_sym] = self[iv]
330
+ key = iv.to_s[1..-1]
331
+ result[key.to_sym] = instance_variable_get(iv)
332
+ end
333
+
334
+ if result[:allow_duplicate_key].nil?
335
+ result.delete(:allow_duplicate_key)
294
336
  end
337
+
295
338
  result
296
339
  end
297
340
 
@@ -302,6 +345,9 @@ module JSON
302
345
  # created this method raises a
303
346
  # GeneratorError exception.
304
347
  def generate(obj, anIO = nil)
348
+ return dup.generate(obj, anIO) if frozen?
349
+
350
+ depth = @depth
305
351
  if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
306
352
  !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
307
353
  result = generate_json(obj, ''.dup)
@@ -318,10 +364,8 @@ module JSON
318
364
  else
319
365
  result
320
366
  end
321
- end
322
-
323
- def generate_new(obj, anIO = nil) # :nodoc:
324
- dup.generate(obj, anIO)
367
+ ensure
368
+ @depth = depth unless frozen?
325
369
  end
326
370
 
327
371
  # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
@@ -330,8 +374,17 @@ module JSON
330
374
  when Hash
331
375
  buf << '{'
332
376
  first = true
377
+ key_type = nil
333
378
  obj.each_pair do |k,v|
334
- buf << ',' unless first
379
+ if first
380
+ key_type = k.class
381
+ else
382
+ if key_type && !@allow_duplicate_key && key_type != k.class
383
+ key_type = nil # stop checking
384
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
385
+ end
386
+ buf << ','
387
+ end
335
388
 
336
389
  key_str = k.to_s
337
390
  if key_str.class == String
@@ -398,6 +451,8 @@ module JSON
398
451
 
399
452
  # Return the value returned by method +name+.
400
453
  def [](name)
454
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
455
+
401
456
  if respond_to?(name)
402
457
  __send__(name)
403
458
  else
@@ -407,6 +462,8 @@ module JSON
407
462
  end
408
463
 
409
464
  def []=(name, value)
465
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
466
+
410
467
  if respond_to?(name_writer = "#{name}=")
411
468
  __send__ name_writer, value
412
469
  else
@@ -424,10 +481,10 @@ module JSON
424
481
  state = State.from_state(state) if state
425
482
  if state&.strict?
426
483
  value = self
427
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
484
+ if state.strict? && !Generator.native_type?(value)
428
485
  if state.as_json
429
- value = state.as_json.call(value)
430
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
486
+ value = state.as_json.call(value, false)
487
+ unless Generator.native_type?(value)
431
488
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
432
489
  end
433
490
  value.to_json(state)
@@ -449,33 +506,54 @@ module JSON
449
506
  # _depth_ is used to find out nesting depth, to indent accordingly.
450
507
  def to_json(state = nil, *)
451
508
  state = State.from_state(state)
509
+ depth = state.depth
452
510
  state.check_max_nesting
453
511
  json_transform(state)
512
+ ensure
513
+ state.depth = depth
454
514
  end
455
515
 
456
516
  private
457
517
 
458
- def json_shift(state)
459
- state.object_nl.empty? or return ''
460
- state.indent * state.depth
461
- end
462
-
463
518
  def json_transform(state)
464
519
  depth = state.depth += 1
465
520
 
466
521
  if empty?
467
522
  state.depth -= 1
468
- return '{}'
523
+ return +'{}'
469
524
  end
470
525
 
471
526
  delim = ",#{state.object_nl}"
472
- result = +"{#{state.object_nl}"
527
+ result = "{#{state.object_nl}"
473
528
  first = true
529
+ key_type = nil
474
530
  indent = !state.object_nl.empty?
475
531
  each { |key, value|
476
- result << delim unless first
532
+ if first
533
+ key_type = key.class
534
+ else
535
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
536
+ key_type = nil # stop checking
537
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
538
+ end
539
+ result << delim
540
+ end
477
541
  result << state.indent * depth if indent
478
542
 
543
+ if state.strict?
544
+ if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
545
+ key = state.as_json.call(key, true)
546
+ end
547
+
548
+ unless Generator.native_key?(key)
549
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
550
+ end
551
+
552
+ unless Generator.valid_encoding?(key)
553
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
554
+ end
555
+ end
556
+
479
557
  key_str = key.to_s
480
558
  if key_str.is_a?(String)
481
559
  key_json = key_str.to_json(state)
@@ -483,25 +561,27 @@ module JSON
483
561
  raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String"
484
562
  end
485
563
 
486
- result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
487
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
564
+ result = "#{result}#{key_json}#{state.space_before}:#{state.space}"
565
+ if state.strict? && !Generator.native_type?(value)
488
566
  if state.as_json
489
- value = state.as_json.call(value)
490
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
567
+ value = state.as_json.call(value, false)
568
+ unless Generator.native_type?(value)
491
569
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
492
570
  end
493
571
  result << value.to_json(state)
572
+ state.depth = depth
494
573
  else
495
574
  raise GeneratorError.new("#{value.class} not allowed in JSON", value)
496
575
  end
497
576
  elsif value.respond_to?(:to_json)
498
577
  result << value.to_json(state)
578
+ state.depth = depth
499
579
  else
500
580
  result << %{"#{String(value)}"}
501
581
  end
502
582
  first = false
503
583
  }
504
- depth = state.depth -= 1
584
+ depth -= 1
505
585
  unless first
506
586
  result << state.object_nl
507
587
  result << state.indent * depth if indent
@@ -518,8 +598,11 @@ module JSON
518
598
  # produced JSON string output further.
519
599
  def to_json(state = nil, *)
520
600
  state = State.from_state(state)
601
+ depth = state.depth
521
602
  state.check_max_nesting
522
603
  json_transform(state)
604
+ ensure
605
+ state.depth = depth
523
606
  end
524
607
 
525
608
  private
@@ -529,7 +612,7 @@ module JSON
529
612
 
530
613
  if empty?
531
614
  state.depth -= 1
532
- return '[]'
615
+ return +'[]'
533
616
  end
534
617
 
535
618
  result = '['.dup
@@ -545,10 +628,10 @@ module JSON
545
628
  each { |value|
546
629
  result << delim unless first
547
630
  result << state.indent * depth if indent
548
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value)
631
+ if state.strict? && !Generator.native_type?(value)
549
632
  if state.as_json
550
- value = state.as_json.call(value)
551
- unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value
633
+ value = state.as_json.call(value, false)
634
+ unless Generator.native_type?(value)
552
635
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
553
636
  end
554
637
  result << value.to_json(state)
@@ -557,12 +640,13 @@ module JSON
557
640
  end
558
641
  elsif value.respond_to?(:to_json)
559
642
  result << value.to_json(state)
643
+ state.depth = depth
560
644
  else
561
645
  result << %{"#{String(value)}"}
562
646
  end
563
647
  first = false
564
648
  }
565
- depth = state.depth -= 1
649
+ depth -= 1
566
650
  result << state.array_nl
567
651
  result << state.indent * depth if indent
568
652
  result << ']'
@@ -582,11 +666,14 @@ module JSON
582
666
  if state.allow_nan?
583
667
  to_s
584
668
  elsif state.strict? && state.as_json
585
- casted_value = state.as_json.call(self)
669
+ casted_value = state.as_json.call(self, false)
586
670
 
587
671
  if casted_value.equal?(self)
588
672
  raise GeneratorError.new("#{self} not allowed in JSON", self)
589
673
  end
674
+ unless Generator.native_type?(casted_value)
675
+ raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
676
+ end
590
677
 
591
678
  state.check_max_nesting
592
679
  state.depth += 1
@@ -619,14 +706,25 @@ module JSON
619
706
  # \u????.
620
707
  def to_json(state = nil, *args)
621
708
  state = State.from_state(state)
622
- if encoding == ::Encoding::UTF_8
623
- unless valid_encoding?
709
+ string = self
710
+
711
+ if state.strict? && state.as_json
712
+ unless Generator.valid_encoding?(string)
713
+ string = state.as_json.call(string, false)
714
+ unless string.is_a?(::String)
715
+ return string.to_json(state, *args)
716
+ end
717
+ end
718
+ end
719
+
720
+ if string.encoding == ::Encoding::UTF_8
721
+ unless string.valid_encoding?
624
722
  raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
625
723
  end
626
- string = self
627
724
  else
628
- string = encode(::Encoding::UTF_8)
725
+ string = string.encode(::Encoding::UTF_8)
629
726
  end
727
+
630
728
  if state.ascii_only?
631
729
  %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
632
730
  else
@@ -635,54 +733,21 @@ module JSON
635
733
  rescue Encoding::UndefinedConversionError => error
636
734
  raise ::JSON::GeneratorError.new(error.message, self)
637
735
  end
638
-
639
- # Module that holds the extending methods if, the String module is
640
- # included.
641
- module Extend
642
- # Raw Strings are JSON Objects (the raw bytes are stored in an
643
- # array for the key "raw"). The Ruby String can be created by this
644
- # module method.
645
- def json_create(o)
646
- o['raw'].pack('C*')
647
- end
648
- end
649
-
650
- # Extends _modul_ with the String::Extend module.
651
- def self.included(modul)
652
- modul.extend Extend
653
- end
654
-
655
- # This method creates a raw object hash, that can be nested into
656
- # other data structures and will be unparsed as a raw string. This
657
- # method should be used, if you want to convert raw strings to JSON
658
- # instead of UTF-8 strings, e. g. binary data.
659
- def to_json_raw_object
660
- {
661
- JSON.create_id => self.class.name,
662
- 'raw' => self.unpack('C*'),
663
- }
664
- end
665
-
666
- # This method creates a JSON text from the result of
667
- # a call to to_json_raw_object of this String.
668
- def to_json_raw(*args)
669
- to_json_raw_object.to_json(*args)
670
- end
671
736
  end
672
737
 
673
738
  module TrueClass
674
739
  # Returns a JSON string for true: 'true'.
675
- def to_json(*) 'true' end
740
+ def to_json(*) +'true' end
676
741
  end
677
742
 
678
743
  module FalseClass
679
744
  # Returns a JSON string for false: 'false'.
680
- def to_json(*) 'false' end
745
+ def to_json(*) +'false' end
681
746
  end
682
747
 
683
748
  module NilClass
684
749
  # Returns a JSON string for nil: 'null'.
685
- def to_json(*) 'null' end
750
+ def to_json(*) +'null' end
686
751
  end
687
752
  end
688
753
  end
data/lib/json/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.10.2'
4
+ VERSION = '2.19.9'
5
5
  end
data/lib/json.rb CHANGED
@@ -6,6 +6,15 @@ require 'json/common'
6
6
  #
7
7
  # \JSON is a lightweight data-interchange format.
8
8
  #
9
+ # \JSON is easy for us humans to read and write,
10
+ # and equally simple for machines to read (parse) and write (generate).
11
+ #
12
+ # \JSON is language-independent, making it an ideal interchange format
13
+ # for applications in differing programming languages
14
+ # and on differing operating systems.
15
+ #
16
+ # == \JSON Values
17
+ #
9
18
  # A \JSON value is one of the following:
10
19
  # - Double-quoted text: <tt>"foo"</tt>.
11
20
  # - Number: +1+, +1.0+, +2.0e2+.
@@ -127,6 +136,24 @@ require 'json/common'
127
136
  #
128
137
  # ---
129
138
  #
139
+ # Option +allow_duplicate_key+ specifies whether duplicate keys in objects
140
+ # should be ignored or cause an error to be raised:
141
+ #
142
+ # When not specified:
143
+ # # The last value is used and a deprecation warning emitted.
144
+ # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
145
+ # # warning: detected duplicate keys in JSON object.
146
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
147
+ #
148
+ # When set to `+true+`
149
+ # # The last value is used.
150
+ # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
151
+ #
152
+ # When set to `+false+`, the future default:
153
+ # JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
154
+ #
155
+ # ---
156
+ #
130
157
  # Option +allow_nan+ (boolean) specifies whether to allow
131
158
  # NaN, Infinity, and MinusInfinity in +source+;
132
159
  # defaults to +false+.
@@ -143,8 +170,47 @@ require 'json/common'
143
170
  # ruby = JSON.parse(source, {allow_nan: true})
144
171
  # ruby # => [NaN, Infinity, -Infinity]
145
172
  #
173
+ # ---
174
+ #
175
+ # Option +allow_trailing_comma+ (boolean) specifies whether to allow
176
+ # trailing commas in objects and arrays;
177
+ # defaults to +false+.
178
+ #
179
+ # With the default, +false+:
180
+ # JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError)
181
+ #
182
+ # When enabled:
183
+ # JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
184
+ #
185
+ # ---
186
+ #
187
+ # Option +allow_control_characters+ (boolean) specifies whether to allow
188
+ # unescaped ASCII control characters, such as newlines, in strings;
189
+ # defaults to +false+.
190
+ #
191
+ # With the default, +false+:
192
+ # JSON.parse(%{"Hello\nWorld"}) # invalid ASCII control character in string (JSON::ParserError)
193
+ #
194
+ # When enabled:
195
+ # JSON.parse(%{"Hello\nWorld"}, allow_control_characters: true) # => "Hello\nWorld"
196
+ #
197
+ # ---
198
+ #
199
+ # Option +allow_invalid_escape+ (boolean) specifies whether to ignore backslahes that are followed
200
+ # by an invalid escape character in strings;
201
+ # defaults to +false+.
202
+ #
203
+ # With the default, +false+:
204
+ # JSON.parse('"Hell\o"') # invalid escape character in string (JSON::ParserError)
205
+ #
206
+ # When enabled:
207
+ # JSON.parse('"Hell\o"', allow_invalid_escape: true) # => "Hello"
208
+ #
146
209
  # ====== Output Options
147
210
  #
211
+ # Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
212
+ # defaults to +false+.
213
+ #
148
214
  # Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
149
215
  # should be Symbols;
150
216
  # defaults to +false+ (use Strings).
@@ -269,8 +335,27 @@ require 'json/common'
269
335
  # JSON.generate(JSON::MinusInfinity)
270
336
  #
271
337
  # Allow:
272
- # ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
273
- # JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
338
+ # ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity]
339
+ # JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
340
+ #
341
+ # ---
342
+ #
343
+ # Option +allow_duplicate_key+ (boolean) specifies whether
344
+ # hashes with duplicate keys should be allowed or produce an error.
345
+ # defaults to emit a deprecation warning.
346
+ #
347
+ # With the default, (not set):
348
+ # Warning[:deprecated] = true
349
+ # JSON.generate({ foo: 1, "foo" => 2 })
350
+ # # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
351
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
352
+ # # => '{"foo":1,"foo":2}'
353
+ #
354
+ # With <tt>false</tt>
355
+ # JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
356
+ # # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
357
+ #
358
+ # In version 3.0, <tt>false</tt> will become the default.
274
359
  #
275
360
  # ---
276
361
  #
@@ -351,6 +436,9 @@ require 'json/common'
351
436
  #
352
437
  # == \JSON Additions
353
438
  #
439
+ # Note that JSON Additions must only be used with trusted data, and is
440
+ # deprecated.
441
+ #
354
442
  # When you "round trip" a non-\String object from Ruby to \JSON and back,
355
443
  # you have a new \String, instead of the object you began with:
356
444
  # ruby0 = Range.new(0, 2)