json 2.13.2 → 2.17.1

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.
data/lib/json/add/core.rb CHANGED
@@ -7,6 +7,7 @@ require 'json/add/date_time'
7
7
  require 'json/add/exception'
8
8
  require 'json/add/range'
9
9
  require 'json/add/regexp'
10
+ require 'json/add/string'
10
11
  require 'json/add/struct'
11
12
  require 'json/add/symbol'
12
13
  require 'json/add/time'
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
3
+ require 'json'
4
+ end
5
+
6
+ class String
7
+ # call-seq: json_create(o)
8
+ #
9
+ # Raw Strings are JSON Objects (the raw bytes are stored in an array for the
10
+ # key "raw"). The Ruby String can be created by this class method.
11
+ def self.json_create(object)
12
+ object["raw"].pack("C*")
13
+ end
14
+
15
+ # call-seq: to_json_raw_object()
16
+ #
17
+ # This method creates a raw object hash, that can be nested into
18
+ # other data structures and will be generated as a raw string. This
19
+ # method should be used, if you want to convert raw strings to JSON
20
+ # instead of UTF-8 strings, e. g. binary data.
21
+ def to_json_raw_object
22
+ {
23
+ JSON.create_id => self.class.name,
24
+ "raw" => unpack("C*"),
25
+ }
26
+ end
27
+
28
+ # call-seq: to_json_raw(*args)
29
+ #
30
+ # This method creates a JSON text from the result of a call to
31
+ # to_json_raw_object of this String.
32
+ def to_json_raw(...)
33
+ to_json_raw_object.to_json(...)
34
+ end
35
+ end
data/lib/json/common.rb CHANGED
@@ -71,9 +71,14 @@ module JSON
71
71
  end
72
72
  when object_class
73
73
  if opts[:create_additions] != false
74
- if class_name = object[JSON.create_id]
75
- klass = JSON.deep_const_get(class_name)
76
- if (klass.respond_to?(:json_creatable?) && klass.json_creatable?) || klass.respond_to?(:json_create)
74
+ if class_path = object[JSON.create_id]
75
+ klass = begin
76
+ Object.const_get(class_path)
77
+ rescue NameError => e
78
+ raise ArgumentError, "can't get const #{class_path}: #{e}"
79
+ end
80
+
81
+ if klass.respond_to?(:json_creatable?) ? klass.json_creatable? : klass.respond_to?(:json_create)
77
82
  create_additions_warning if create_additions.nil?
78
83
  object = klass.json_create(object)
79
84
  end
@@ -97,7 +102,7 @@ module JSON
97
102
 
98
103
  class << self
99
104
  def deprecation_warning(message, uplevel = 3) # :nodoc:
100
- gem_root = File.expand_path("../../../", __FILE__) + "/"
105
+ gem_root = File.expand_path("..", __dir__) + "/"
101
106
  caller_locations(uplevel, 10).each do |frame|
102
107
  if frame.path.nil? || frame.path.start_with?(gem_root) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c")
103
108
  uplevel += 1
@@ -147,16 +152,6 @@ module JSON
147
152
  const_set :Parser, parser
148
153
  end
149
154
 
150
- # Return the constant located at _path_. The format of _path_ has to be
151
- # either ::A::B::C or A::B::C. In any case, A has to be located at the top
152
- # level (absolute namespace path?). If there doesn't exist a constant at
153
- # the given path, an ArgumentError is raised.
154
- def deep_const_get(path) # :nodoc:
155
- Object.const_get(path)
156
- rescue NameError => e
157
- raise ArgumentError, "can't get const #{path}: #{e}"
158
- end
159
-
160
155
  # Set the module _generator_ to be used by JSON.
161
156
  def generator=(generator) # :nodoc:
162
157
  old, $VERBOSE = $VERBOSE, nil
@@ -186,6 +181,25 @@ module JSON
186
181
 
187
182
  private
188
183
 
184
+ # Called from the extension when a hash has both string and symbol keys
185
+ def on_mixed_keys_hash(hash, do_raise)
186
+ set = {}
187
+ hash.each_key do |key|
188
+ key_str = key.to_s
189
+
190
+ if set[key_str]
191
+ message = "detected duplicate key #{key_str.inspect} in #{hash.inspect}"
192
+ if do_raise
193
+ raise GeneratorError, message
194
+ else
195
+ deprecation_warning("#{message}.\nThis will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`")
196
+ end
197
+ else
198
+ set[key_str] = true
199
+ end
200
+ end
201
+ end
202
+
189
203
  def deprecated_singleton_attr_accessor(*attrs)
190
204
  args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : ""
191
205
  attrs.each do |attr|
@@ -391,7 +405,7 @@ module JSON
391
405
  #
392
406
  # Returns a \String containing the generated \JSON data.
393
407
  #
394
- # See also JSON.fast_generate, JSON.pretty_generate.
408
+ # See also JSON.pretty_generate.
395
409
  #
396
410
  # Argument +obj+ is the Ruby object to be converted to \JSON.
397
411
  #
@@ -536,6 +550,7 @@ module JSON
536
550
  :create_additions => nil,
537
551
  }
538
552
  # :call-seq:
553
+ # JSON.unsafe_load(source, options = {}) -> object
539
554
  # JSON.unsafe_load(source, proc = nil, options = {}) -> object
540
555
  #
541
556
  # Returns the Ruby objects created by parsing the given +source+.
@@ -643,6 +658,7 @@ module JSON
643
658
  # when Array
644
659
  # obj.map! {|v| deserialize_obj v }
645
660
  # end
661
+ # obj
646
662
  # })
647
663
  # pp ruby
648
664
  # Output:
@@ -666,7 +682,12 @@ module JSON
666
682
  #
667
683
  def unsafe_load(source, proc = nil, options = nil)
668
684
  opts = if options.nil?
669
- _unsafe_load_default_options
685
+ if proc && proc.is_a?(Hash)
686
+ options, proc = proc, nil
687
+ options
688
+ else
689
+ _unsafe_load_default_options
690
+ end
670
691
  else
671
692
  _unsafe_load_default_options.merge(options)
672
693
  end
@@ -684,12 +705,17 @@ module JSON
684
705
  if opts[:allow_blank] && (source.nil? || source.empty?)
685
706
  source = 'null'
686
707
  end
687
- result = parse(source, opts)
688
- recurse_proc(result, &proc) if proc
689
- result
708
+
709
+ if proc
710
+ opts = opts.dup
711
+ opts[:on_load] = proc.to_proc
712
+ end
713
+
714
+ parse(source, opts)
690
715
  end
691
716
 
692
717
  # :call-seq:
718
+ # JSON.load(source, options = {}) -> object
693
719
  # JSON.load(source, proc = nil, options = {}) -> object
694
720
  #
695
721
  # Returns the Ruby objects created by parsing the given +source+.
@@ -803,6 +829,7 @@ module JSON
803
829
  # when Array
804
830
  # obj.map! {|v| deserialize_obj v }
805
831
  # end
832
+ # obj
806
833
  # })
807
834
  # pp ruby
808
835
  # Output:
@@ -825,8 +852,18 @@ module JSON
825
852
  # @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
826
853
  #
827
854
  def load(source, proc = nil, options = nil)
855
+ if proc && options.nil? && proc.is_a?(Hash)
856
+ options = proc
857
+ proc = nil
858
+ end
859
+
828
860
  opts = if options.nil?
829
- _load_default_options
861
+ if proc && proc.is_a?(Hash)
862
+ options, proc = proc, nil
863
+ options
864
+ else
865
+ _load_default_options
866
+ end
830
867
  else
831
868
  _load_default_options.merge(options)
832
869
  end
@@ -1002,7 +1039,7 @@ module JSON
1002
1039
  # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
1003
1040
  #
1004
1041
  # For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
1005
- # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1042
+ # encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
1006
1043
  # \JSON counterpart:
1007
1044
  #
1008
1045
  # module MyApp
@@ -1028,7 +1065,7 @@ module JSON
1028
1065
  options[:as_json] = as_json if as_json
1029
1066
 
1030
1067
  @state = State.new(options).freeze
1031
- @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options))
1068
+ @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze
1032
1069
  end
1033
1070
 
1034
1071
  # call-seq:
@@ -1037,7 +1074,7 @@ module JSON
1037
1074
  #
1038
1075
  # Serialize the given object into a \JSON document.
1039
1076
  def dump(object, io = nil)
1040
- @state.generate_new(object, io)
1077
+ @state.generate(object, io)
1041
1078
  end
1042
1079
  alias_method :generate, :dump
1043
1080
 
@@ -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}[#module-JSON-label-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
@@ -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 || 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:
@@ -204,7 +217,7 @@ module JSON
204
217
  return if @max_nesting.zero?
205
218
  current_nesting = depth + 1
206
219
  current_nesting > @max_nesting and
207
- raise NestingError, "nesting of #{current_nesting} is too deep"
220
+ raise NestingError, "nesting of #{current_nesting} is too deep. Did you try to serialize objects with circular references?"
208
221
  end
209
222
 
210
223
  # Returns true, if circular data structures are checked,
@@ -271,6 +284,12 @@ module JSON
271
284
  false
272
285
  end
273
286
 
287
+ if opts.key?(:allow_duplicate_key)
288
+ @allow_duplicate_key = !!opts[:allow_duplicate_key]
289
+ else
290
+ @allow_duplicate_key = nil # nil is deprecation
291
+ end
292
+
274
293
  @strict = !!opts[:strict] if opts.key?(:strict)
275
294
 
276
295
  if !opts.key?(:max_nesting) # defaults to 100
@@ -284,14 +303,23 @@ module JSON
284
303
  end
285
304
  alias merge configure
286
305
 
306
+ def allow_duplicate_key? # :nodoc:
307
+ @allow_duplicate_key
308
+ end
309
+
287
310
  # Returns the configuration instance variables as a hash, that can be
288
311
  # passed to the configure method.
289
312
  def to_h
290
313
  result = {}
291
314
  instance_variables.each do |iv|
292
- iv = iv.to_s[1..-1]
293
- result[iv.to_sym] = self[iv]
315
+ key = iv.to_s[1..-1]
316
+ result[key.to_sym] = instance_variable_get(iv)
317
+ end
318
+
319
+ if result[:allow_duplicate_key].nil?
320
+ result.delete(:allow_duplicate_key)
294
321
  end
322
+
295
323
  result
296
324
  end
297
325
 
@@ -302,6 +330,9 @@ module JSON
302
330
  # created this method raises a
303
331
  # GeneratorError exception.
304
332
  def generate(obj, anIO = nil)
333
+ return dup.generate(obj, anIO) if frozen?
334
+
335
+ depth = @depth
305
336
  if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
306
337
  !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
307
338
  result = generate_json(obj, ''.dup)
@@ -318,10 +349,8 @@ module JSON
318
349
  else
319
350
  result
320
351
  end
321
- end
322
-
323
- def generate_new(obj, anIO = nil) # :nodoc:
324
- dup.generate(obj, anIO)
352
+ ensure
353
+ @depth = depth unless frozen?
325
354
  end
326
355
 
327
356
  # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
@@ -330,8 +359,17 @@ module JSON
330
359
  when Hash
331
360
  buf << '{'
332
361
  first = true
362
+ key_type = nil
333
363
  obj.each_pair do |k,v|
334
- buf << ',' unless first
364
+ if first
365
+ key_type = k.class
366
+ else
367
+ if key_type && !@allow_duplicate_key && key_type != k.class
368
+ key_type = nil # stop checking
369
+ JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
370
+ end
371
+ buf << ','
372
+ end
335
373
 
336
374
  key_str = k.to_s
337
375
  if key_str.class == String
@@ -398,6 +436,8 @@ module JSON
398
436
 
399
437
  # Return the value returned by method +name+.
400
438
  def [](name)
439
+ ::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
440
+
401
441
  if respond_to?(name)
402
442
  __send__(name)
403
443
  else
@@ -407,6 +447,8 @@ module JSON
407
447
  end
408
448
 
409
449
  def []=(name, value)
450
+ ::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
451
+
410
452
  if respond_to?(name_writer = "#{name}=")
411
453
  __send__ name_writer, value
412
454
  else
@@ -424,10 +466,10 @@ module JSON
424
466
  state = State.from_state(state) if state
425
467
  if state&.strict?
426
468
  value = self
427
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
469
+ if state.strict? && !Generator.native_type?(value)
428
470
  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
471
+ value = state.as_json.call(value, false)
472
+ unless Generator.native_type?(value)
431
473
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
432
474
  end
433
475
  value.to_json(state)
@@ -449,8 +491,11 @@ module JSON
449
491
  # _depth_ is used to find out nesting depth, to indent accordingly.
450
492
  def to_json(state = nil, *)
451
493
  state = State.from_state(state)
494
+ depth = state.depth
452
495
  state.check_max_nesting
453
496
  json_transform(state)
497
+ ensure
498
+ state.depth = depth
454
499
  end
455
500
 
456
501
  private
@@ -471,11 +516,34 @@ module JSON
471
516
  delim = ",#{state.object_nl}"
472
517
  result = +"{#{state.object_nl}"
473
518
  first = true
519
+ key_type = nil
474
520
  indent = !state.object_nl.empty?
475
521
  each { |key, value|
476
- result << delim unless first
522
+ if first
523
+ key_type = key.class
524
+ else
525
+ if key_type && !state.allow_duplicate_key? && key_type != key.class
526
+ key_type = nil # stop checking
527
+ JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
528
+ end
529
+ result << delim
530
+ end
477
531
  result << state.indent * depth if indent
478
532
 
533
+ if state.strict?
534
+ if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
535
+ key = state.as_json.call(key, true)
536
+ end
537
+
538
+ unless Generator.native_key?(key)
539
+ raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
540
+ end
541
+
542
+ unless Generator.valid_encoding?(key)
543
+ raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
544
+ end
545
+ end
546
+
479
547
  key_str = key.to_s
480
548
  if key_str.is_a?(String)
481
549
  key_json = key_str.to_json(state)
@@ -484,24 +552,26 @@ module JSON
484
552
  end
485
553
 
486
554
  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)
555
+ if state.strict? && !Generator.native_type?(value)
488
556
  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
557
+ value = state.as_json.call(value, false)
558
+ unless Generator.native_type?(value)
491
559
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
492
560
  end
493
561
  result << value.to_json(state)
562
+ state.depth = depth
494
563
  else
495
564
  raise GeneratorError.new("#{value.class} not allowed in JSON", value)
496
565
  end
497
566
  elsif value.respond_to?(:to_json)
498
567
  result << value.to_json(state)
568
+ state.depth = depth
499
569
  else
500
570
  result << %{"#{String(value)}"}
501
571
  end
502
572
  first = false
503
573
  }
504
- depth = state.depth -= 1
574
+ depth -= 1
505
575
  unless first
506
576
  result << state.object_nl
507
577
  result << state.indent * depth if indent
@@ -518,8 +588,11 @@ module JSON
518
588
  # produced JSON string output further.
519
589
  def to_json(state = nil, *)
520
590
  state = State.from_state(state)
591
+ depth = state.depth
521
592
  state.check_max_nesting
522
593
  json_transform(state)
594
+ ensure
595
+ state.depth = depth
523
596
  end
524
597
 
525
598
  private
@@ -545,10 +618,10 @@ module JSON
545
618
  each { |value|
546
619
  result << delim unless first
547
620
  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)
621
+ if state.strict? && !Generator.native_type?(value)
549
622
  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
623
+ value = state.as_json.call(value, false)
624
+ unless Generator.native_type?(value)
552
625
  raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
553
626
  end
554
627
  result << value.to_json(state)
@@ -557,12 +630,13 @@ module JSON
557
630
  end
558
631
  elsif value.respond_to?(:to_json)
559
632
  result << value.to_json(state)
633
+ state.depth = depth
560
634
  else
561
635
  result << %{"#{String(value)}"}
562
636
  end
563
637
  first = false
564
638
  }
565
- depth = state.depth -= 1
639
+ depth -= 1
566
640
  result << state.array_nl
567
641
  result << state.indent * depth if indent
568
642
  result << ']'
@@ -582,11 +656,14 @@ module JSON
582
656
  if state.allow_nan?
583
657
  to_s
584
658
  elsif state.strict? && state.as_json
585
- casted_value = state.as_json.call(self)
659
+ casted_value = state.as_json.call(self, false)
586
660
 
587
661
  if casted_value.equal?(self)
588
662
  raise GeneratorError.new("#{self} not allowed in JSON", self)
589
663
  end
664
+ unless Generator.native_type?(casted_value)
665
+ raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
666
+ end
590
667
 
591
668
  state.check_max_nesting
592
669
  state.depth += 1
@@ -619,14 +696,25 @@ module JSON
619
696
  # \u????.
620
697
  def to_json(state = nil, *args)
621
698
  state = State.from_state(state)
622
- if encoding == ::Encoding::UTF_8
623
- unless valid_encoding?
699
+ string = self
700
+
701
+ if state.strict? && state.as_json
702
+ unless Generator.valid_encoding?(string)
703
+ string = state.as_json.call(string, false)
704
+ unless string.is_a?(::String)
705
+ return string.to_json(state, *args)
706
+ end
707
+ end
708
+ end
709
+
710
+ if string.encoding == ::Encoding::UTF_8
711
+ unless string.valid_encoding?
624
712
  raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
625
713
  end
626
- string = self
627
714
  else
628
- string = encode(::Encoding::UTF_8)
715
+ string = string.encode(::Encoding::UTF_8)
629
716
  end
717
+
630
718
  if state.ascii_only?
631
719
  %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
632
720
  else
@@ -635,39 +723,6 @@ module JSON
635
723
  rescue Encoding::UndefinedConversionError => error
636
724
  raise ::JSON::GeneratorError.new(error.message, self)
637
725
  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
726
  end
672
727
 
673
728
  module TrueClass
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.13.2'
4
+ VERSION = '2.17.1'
5
5
  end
data/lib/json.rb CHANGED
@@ -133,7 +133,7 @@ require 'json/common'
133
133
  # When not specified:
134
134
  # # The last value is used and a deprecation warning emitted.
135
135
  # JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
136
- # # waring: detected duplicate keys in JSON object.
136
+ # # warning: detected duplicate keys in JSON object.
137
137
  # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
138
138
  #
139
139
  # When set to `+true+`
@@ -307,6 +307,25 @@ require 'json/common'
307
307
  #
308
308
  # ---
309
309
  #
310
+ # Option +allow_duplicate_key+ (boolean) specifies whether
311
+ # hashes with duplicate keys should be allowed or produce an error.
312
+ # defaults to emit a deprecation warning.
313
+ #
314
+ # With the default, (not set):
315
+ # Warning[:deprecated] = true
316
+ # JSON.generate({ foo: 1, "foo" => 2 })
317
+ # # warning: detected duplicate key "foo" in {foo: 1, "foo" => 2}.
318
+ # # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
319
+ # # => '{"foo":1,"foo":2}'
320
+ #
321
+ # With <tt>false</tt>
322
+ # JSON.generate({ foo: 1, "foo" => 2 }, allow_duplicate_key: false)
323
+ # # detected duplicate key "foo" in {foo: 1, "foo" => 2} (JSON::GeneratorError)
324
+ #
325
+ # In version 3.0, <tt>false</tt> will become the default.
326
+ #
327
+ # ---
328
+ #
310
329
  # Option +max_nesting+ (\Integer) specifies the maximum nesting depth
311
330
  # in +obj+; defaults to +100+.
312
331
  #
@@ -384,6 +403,9 @@ require 'json/common'
384
403
  #
385
404
  # == \JSON Additions
386
405
  #
406
+ # Note that JSON Additions must only be used with trusted data, and is
407
+ # deprecated.
408
+ #
387
409
  # When you "round trip" a non-\String object from Ruby to \JSON and back,
388
410
  # you have a new \String, instead of the object you began with:
389
411
  # ruby0 = Range.new(0, 2)