json 2.13.2 → 2.16.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 +4 -4
- data/CHANGES.md +56 -8
- data/LEGAL +12 -0
- data/README.md +19 -1
- data/ext/json/ext/fbuffer/fbuffer.h +26 -49
- data/ext/json/ext/generator/generator.c +277 -217
- data/ext/json/ext/json.h +92 -0
- data/ext/json/ext/parser/extconf.rb +2 -0
- data/ext/json/ext/parser/parser.c +409 -320
- data/ext/json/ext/simd/simd.h +15 -12
- data/ext/json/ext/vendor/fpconv.c +12 -11
- data/ext/json/ext/vendor/ryu.h +819 -0
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/string.rb +35 -0
- data/lib/json/common.rb +39 -19
- data/lib/json/ext/generator/state.rb +11 -14
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +96 -50
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +23 -1
- metadata +6 -3
data/lib/json/add/core.rb
CHANGED
|
@@ -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
|
|
75
|
-
klass =
|
|
76
|
-
|
|
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("
|
|
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.
|
|
408
|
+
# See also JSON.pretty_generate.
|
|
395
409
|
#
|
|
396
410
|
# Argument +obj+ is the Ruby object to be converted to \JSON.
|
|
397
411
|
#
|
|
@@ -643,6 +657,7 @@ module JSON
|
|
|
643
657
|
# when Array
|
|
644
658
|
# obj.map! {|v| deserialize_obj v }
|
|
645
659
|
# end
|
|
660
|
+
# obj
|
|
646
661
|
# })
|
|
647
662
|
# pp ruby
|
|
648
663
|
# Output:
|
|
@@ -684,9 +699,13 @@ module JSON
|
|
|
684
699
|
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
685
700
|
source = 'null'
|
|
686
701
|
end
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
702
|
+
|
|
703
|
+
if proc
|
|
704
|
+
opts = opts.dup
|
|
705
|
+
opts[:on_load] = proc.to_proc
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
parse(source, opts)
|
|
690
709
|
end
|
|
691
710
|
|
|
692
711
|
# :call-seq:
|
|
@@ -803,6 +822,7 @@ module JSON
|
|
|
803
822
|
# when Array
|
|
804
823
|
# obj.map! {|v| deserialize_obj v }
|
|
805
824
|
# end
|
|
825
|
+
# obj
|
|
806
826
|
# })
|
|
807
827
|
# pp ruby
|
|
808
828
|
# Output:
|
|
@@ -1002,7 +1022,7 @@ module JSON
|
|
|
1002
1022
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
|
|
1003
1023
|
#
|
|
1004
1024
|
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
|
1005
|
-
#
|
|
1025
|
+
# encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
|
1006
1026
|
# \JSON counterpart:
|
|
1007
1027
|
#
|
|
1008
1028
|
# module MyApp
|
|
@@ -8,20 +8,8 @@ module JSON
|
|
|
8
8
|
#
|
|
9
9
|
# Instantiates a new State object, configured by _opts_.
|
|
10
10
|
#
|
|
11
|
-
#
|
|
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
|
data/lib/json/generic_object.rb
CHANGED
|
@@ -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,6 +303,10 @@ 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
|
|
@@ -292,6 +315,11 @@ module JSON
|
|
|
292
315
|
iv = iv.to_s[1..-1]
|
|
293
316
|
result[iv.to_sym] = self[iv]
|
|
294
317
|
end
|
|
318
|
+
|
|
319
|
+
if result[:allow_duplicate_key].nil?
|
|
320
|
+
result.delete(:allow_duplicate_key)
|
|
321
|
+
end
|
|
322
|
+
|
|
295
323
|
result
|
|
296
324
|
end
|
|
297
325
|
|
|
@@ -324,14 +352,27 @@ module JSON
|
|
|
324
352
|
dup.generate(obj, anIO)
|
|
325
353
|
end
|
|
326
354
|
|
|
355
|
+
private def initialize_copy(_orig)
|
|
356
|
+
@depth = 0
|
|
357
|
+
end
|
|
358
|
+
|
|
327
359
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
|
328
360
|
private def generate_json(obj, buf)
|
|
329
361
|
case obj
|
|
330
362
|
when Hash
|
|
331
363
|
buf << '{'
|
|
332
364
|
first = true
|
|
365
|
+
key_type = nil
|
|
333
366
|
obj.each_pair do |k,v|
|
|
334
|
-
|
|
367
|
+
if first
|
|
368
|
+
key_type = k.class
|
|
369
|
+
else
|
|
370
|
+
if key_type && !@allow_duplicate_key && key_type != k.class
|
|
371
|
+
key_type = nil # stop checking
|
|
372
|
+
JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
|
|
373
|
+
end
|
|
374
|
+
buf << ','
|
|
375
|
+
end
|
|
335
376
|
|
|
336
377
|
key_str = k.to_s
|
|
337
378
|
if key_str.class == String
|
|
@@ -398,6 +439,8 @@ module JSON
|
|
|
398
439
|
|
|
399
440
|
# Return the value returned by method +name+.
|
|
400
441
|
def [](name)
|
|
442
|
+
::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
|
|
443
|
+
|
|
401
444
|
if respond_to?(name)
|
|
402
445
|
__send__(name)
|
|
403
446
|
else
|
|
@@ -407,6 +450,8 @@ module JSON
|
|
|
407
450
|
end
|
|
408
451
|
|
|
409
452
|
def []=(name, value)
|
|
453
|
+
::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
|
|
454
|
+
|
|
410
455
|
if respond_to?(name_writer = "#{name}=")
|
|
411
456
|
__send__ name_writer, value
|
|
412
457
|
else
|
|
@@ -424,10 +469,10 @@ module JSON
|
|
|
424
469
|
state = State.from_state(state) if state
|
|
425
470
|
if state&.strict?
|
|
426
471
|
value = self
|
|
427
|
-
if state.strict? && !(
|
|
472
|
+
if state.strict? && !Generator.native_type?(value)
|
|
428
473
|
if state.as_json
|
|
429
|
-
value = state.as_json.call(value)
|
|
430
|
-
unless
|
|
474
|
+
value = state.as_json.call(value, false)
|
|
475
|
+
unless Generator.native_type?(value)
|
|
431
476
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
432
477
|
end
|
|
433
478
|
value.to_json(state)
|
|
@@ -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
|
-
|
|
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,10 +552,10 @@ module JSON
|
|
|
484
552
|
end
|
|
485
553
|
|
|
486
554
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
487
|
-
if state.strict? && !(
|
|
555
|
+
if state.strict? && !Generator.native_type?(value)
|
|
488
556
|
if state.as_json
|
|
489
|
-
value = state.as_json.call(value)
|
|
490
|
-
unless
|
|
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)
|
|
@@ -545,10 +613,10 @@ module JSON
|
|
|
545
613
|
each { |value|
|
|
546
614
|
result << delim unless first
|
|
547
615
|
result << state.indent * depth if indent
|
|
548
|
-
if state.strict? && !(
|
|
616
|
+
if state.strict? && !Generator.native_type?(value)
|
|
549
617
|
if state.as_json
|
|
550
|
-
value = state.as_json.call(value)
|
|
551
|
-
unless
|
|
618
|
+
value = state.as_json.call(value, false)
|
|
619
|
+
unless Generator.native_type?(value)
|
|
552
620
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
553
621
|
end
|
|
554
622
|
result << value.to_json(state)
|
|
@@ -582,7 +650,7 @@ module JSON
|
|
|
582
650
|
if state.allow_nan?
|
|
583
651
|
to_s
|
|
584
652
|
elsif state.strict? && state.as_json
|
|
585
|
-
casted_value = state.as_json.call(self)
|
|
653
|
+
casted_value = state.as_json.call(self, false)
|
|
586
654
|
|
|
587
655
|
if casted_value.equal?(self)
|
|
588
656
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
@@ -619,14 +687,25 @@ module JSON
|
|
|
619
687
|
# \u????.
|
|
620
688
|
def to_json(state = nil, *args)
|
|
621
689
|
state = State.from_state(state)
|
|
622
|
-
|
|
623
|
-
|
|
690
|
+
string = self
|
|
691
|
+
|
|
692
|
+
if state.strict? && state.as_json
|
|
693
|
+
unless Generator.valid_encoding?(string)
|
|
694
|
+
string = state.as_json.call(string, false)
|
|
695
|
+
unless string.is_a?(::String)
|
|
696
|
+
return string.to_json(state, *args)
|
|
697
|
+
end
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
if string.encoding == ::Encoding::UTF_8
|
|
702
|
+
unless string.valid_encoding?
|
|
624
703
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
|
|
625
704
|
end
|
|
626
|
-
string = self
|
|
627
705
|
else
|
|
628
|
-
string = encode(::Encoding::UTF_8)
|
|
706
|
+
string = string.encode(::Encoding::UTF_8)
|
|
629
707
|
end
|
|
708
|
+
|
|
630
709
|
if state.ascii_only?
|
|
631
710
|
%("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
|
|
632
711
|
else
|
|
@@ -635,39 +714,6 @@ module JSON
|
|
|
635
714
|
rescue Encoding::UndefinedConversionError => error
|
|
636
715
|
raise ::JSON::GeneratorError.new(error.message, self)
|
|
637
716
|
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
717
|
end
|
|
672
718
|
|
|
673
719
|
module TrueClass
|
data/lib/json/version.rb
CHANGED
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
|
-
# #
|
|
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)
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: This is a JSON implementation as a Ruby extension in C.
|
|
13
13
|
email: flori@ping.de
|
|
@@ -26,12 +26,14 @@ files:
|
|
|
26
26
|
- ext/json/ext/fbuffer/fbuffer.h
|
|
27
27
|
- ext/json/ext/generator/extconf.rb
|
|
28
28
|
- ext/json/ext/generator/generator.c
|
|
29
|
+
- ext/json/ext/json.h
|
|
29
30
|
- ext/json/ext/parser/extconf.rb
|
|
30
31
|
- ext/json/ext/parser/parser.c
|
|
31
32
|
- ext/json/ext/simd/conf.rb
|
|
32
33
|
- ext/json/ext/simd/simd.h
|
|
33
34
|
- ext/json/ext/vendor/fpconv.c
|
|
34
35
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
36
|
+
- ext/json/ext/vendor/ryu.h
|
|
35
37
|
- json.gemspec
|
|
36
38
|
- lib/json.rb
|
|
37
39
|
- lib/json/add/bigdecimal.rb
|
|
@@ -45,6 +47,7 @@ files:
|
|
|
45
47
|
- lib/json/add/rational.rb
|
|
46
48
|
- lib/json/add/regexp.rb
|
|
47
49
|
- lib/json/add/set.rb
|
|
50
|
+
- lib/json/add/string.rb
|
|
48
51
|
- lib/json/add/struct.rb
|
|
49
52
|
- lib/json/add/symbol.rb
|
|
50
53
|
- lib/json/add/time.rb
|
|
@@ -81,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
81
84
|
- !ruby/object:Gem::Version
|
|
82
85
|
version: '0'
|
|
83
86
|
requirements: []
|
|
84
|
-
rubygems_version: 3.6.
|
|
87
|
+
rubygems_version: 3.6.9
|
|
85
88
|
specification_version: 4
|
|
86
89
|
summary: JSON Implementation for Ruby
|
|
87
90
|
test_files: []
|