json 2.10.2 → 2.15.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.
- checksums.yaml +4 -4
- data/CHANGES.md +110 -7
- data/README.md +16 -1
- data/ext/json/ext/fbuffer/fbuffer.h +110 -19
- data/ext/json/ext/generator/extconf.rb +6 -0
- data/ext/json/ext/generator/generator.c +543 -196
- data/ext/json/ext/parser/extconf.rb +5 -2
- data/ext/json/ext/parser/parser.c +339 -268
- data/ext/json/ext/simd/conf.rb +24 -0
- data/ext/json/ext/simd/simd.h +188 -0
- data/ext/json/ext/vendor/fpconv.c +480 -0
- data/ext/json/ext/vendor/jeaiii-ltoa.h +267 -0
- data/json.gemspec +2 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/string.rb +35 -0
- data/lib/json/common.rb +312 -169
- data/lib/json/ext/generator/state.rb +7 -14
- data/lib/json/ext.rb +2 -2
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +64 -46
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +55 -0
- metadata +8 -3
|
@@ -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]
|
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 =
|
|
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?(
|
|
44
|
+
JSON_LOADED = true unless defined?(JSON::JSON_LOADED)
|
|
45
45
|
end
|
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,14 @@ 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
|
+
|
|
50
58
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
|
51
59
|
# UTF16 big endian characters as \u????, and return it.
|
|
52
60
|
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
|
@@ -117,7 +125,7 @@ module JSON
|
|
|
117
125
|
return new(opts.to_h)
|
|
118
126
|
end
|
|
119
127
|
end
|
|
120
|
-
|
|
128
|
+
new
|
|
121
129
|
end
|
|
122
130
|
|
|
123
131
|
# Instantiates a new State object, configured by _opts_.
|
|
@@ -271,6 +279,12 @@ module JSON
|
|
|
271
279
|
false
|
|
272
280
|
end
|
|
273
281
|
|
|
282
|
+
if opts.key?(:allow_duplicate_key)
|
|
283
|
+
@allow_duplicate_key = !!opts[:allow_duplicate_key]
|
|
284
|
+
else
|
|
285
|
+
@allow_duplicate_key = nil # nil is deprecation
|
|
286
|
+
end
|
|
287
|
+
|
|
274
288
|
@strict = !!opts[:strict] if opts.key?(:strict)
|
|
275
289
|
|
|
276
290
|
if !opts.key?(:max_nesting) # defaults to 100
|
|
@@ -284,6 +298,10 @@ module JSON
|
|
|
284
298
|
end
|
|
285
299
|
alias merge configure
|
|
286
300
|
|
|
301
|
+
def allow_duplicate_key? # :nodoc:
|
|
302
|
+
@allow_duplicate_key
|
|
303
|
+
end
|
|
304
|
+
|
|
287
305
|
# Returns the configuration instance variables as a hash, that can be
|
|
288
306
|
# passed to the configure method.
|
|
289
307
|
def to_h
|
|
@@ -292,6 +310,11 @@ module JSON
|
|
|
292
310
|
iv = iv.to_s[1..-1]
|
|
293
311
|
result[iv.to_sym] = self[iv]
|
|
294
312
|
end
|
|
313
|
+
|
|
314
|
+
if result[:allow_duplicate_key].nil?
|
|
315
|
+
result.delete(:allow_duplicate_key)
|
|
316
|
+
end
|
|
317
|
+
|
|
295
318
|
result
|
|
296
319
|
end
|
|
297
320
|
|
|
@@ -330,8 +353,17 @@ module JSON
|
|
|
330
353
|
when Hash
|
|
331
354
|
buf << '{'
|
|
332
355
|
first = true
|
|
356
|
+
key_type = nil
|
|
333
357
|
obj.each_pair do |k,v|
|
|
334
|
-
|
|
358
|
+
if first
|
|
359
|
+
key_type = k.class
|
|
360
|
+
else
|
|
361
|
+
if key_type && !@allow_duplicate_key && key_type != k.class
|
|
362
|
+
key_type = nil # stop checking
|
|
363
|
+
JSON.send(:on_mixed_keys_hash, obj, !@allow_duplicate_key.nil?)
|
|
364
|
+
end
|
|
365
|
+
buf << ','
|
|
366
|
+
end
|
|
335
367
|
|
|
336
368
|
key_str = k.to_s
|
|
337
369
|
if key_str.class == String
|
|
@@ -424,10 +456,10 @@ module JSON
|
|
|
424
456
|
state = State.from_state(state) if state
|
|
425
457
|
if state&.strict?
|
|
426
458
|
value = self
|
|
427
|
-
if state.strict? && !(
|
|
459
|
+
if state.strict? && !Generator.native_type?(value)
|
|
428
460
|
if state.as_json
|
|
429
|
-
value = state.as_json.call(value)
|
|
430
|
-
unless
|
|
461
|
+
value = state.as_json.call(value, false)
|
|
462
|
+
unless Generator.native_type?(value)
|
|
431
463
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
432
464
|
end
|
|
433
465
|
value.to_json(state)
|
|
@@ -471,11 +503,30 @@ module JSON
|
|
|
471
503
|
delim = ",#{state.object_nl}"
|
|
472
504
|
result = +"{#{state.object_nl}"
|
|
473
505
|
first = true
|
|
506
|
+
key_type = nil
|
|
474
507
|
indent = !state.object_nl.empty?
|
|
475
508
|
each { |key, value|
|
|
476
|
-
|
|
509
|
+
if first
|
|
510
|
+
key_type = key.class
|
|
511
|
+
else
|
|
512
|
+
if key_type && !state.allow_duplicate_key? && key_type != key.class
|
|
513
|
+
key_type = nil # stop checking
|
|
514
|
+
JSON.send(:on_mixed_keys_hash, self, state.allow_duplicate_key? == false)
|
|
515
|
+
end
|
|
516
|
+
result << delim
|
|
517
|
+
end
|
|
477
518
|
result << state.indent * depth if indent
|
|
478
519
|
|
|
520
|
+
if state.strict? && !Generator.native_key?(key)
|
|
521
|
+
if state.as_json
|
|
522
|
+
key = state.as_json.call(key, true)
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
unless Generator.native_key?(key)
|
|
526
|
+
raise GeneratorError.new("#{key.class} not allowed as object key in JSON", value)
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
479
530
|
key_str = key.to_s
|
|
480
531
|
if key_str.is_a?(String)
|
|
481
532
|
key_json = key_str.to_json(state)
|
|
@@ -484,10 +535,10 @@ module JSON
|
|
|
484
535
|
end
|
|
485
536
|
|
|
486
537
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
487
|
-
if state.strict? && !(
|
|
538
|
+
if state.strict? && !Generator.native_type?(value)
|
|
488
539
|
if state.as_json
|
|
489
|
-
value = state.as_json.call(value)
|
|
490
|
-
unless
|
|
540
|
+
value = state.as_json.call(value, false)
|
|
541
|
+
unless Generator.native_type?(value)
|
|
491
542
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
492
543
|
end
|
|
493
544
|
result << value.to_json(state)
|
|
@@ -545,10 +596,10 @@ module JSON
|
|
|
545
596
|
each { |value|
|
|
546
597
|
result << delim unless first
|
|
547
598
|
result << state.indent * depth if indent
|
|
548
|
-
if state.strict? && !(
|
|
599
|
+
if state.strict? && !Generator.native_type?(value)
|
|
549
600
|
if state.as_json
|
|
550
|
-
value = state.as_json.call(value)
|
|
551
|
-
unless
|
|
601
|
+
value = state.as_json.call(value, false)
|
|
602
|
+
unless Generator.native_type?(value)
|
|
552
603
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
553
604
|
end
|
|
554
605
|
result << value.to_json(state)
|
|
@@ -582,7 +633,7 @@ module JSON
|
|
|
582
633
|
if state.allow_nan?
|
|
583
634
|
to_s
|
|
584
635
|
elsif state.strict? && state.as_json
|
|
585
|
-
casted_value = state.as_json.call(self)
|
|
636
|
+
casted_value = state.as_json.call(self, false)
|
|
586
637
|
|
|
587
638
|
if casted_value.equal?(self)
|
|
588
639
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
@@ -635,39 +686,6 @@ module JSON
|
|
|
635
686
|
rescue Encoding::UndefinedConversionError => error
|
|
636
687
|
raise ::JSON::GeneratorError.new(error.message, self)
|
|
637
688
|
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
689
|
end
|
|
672
690
|
|
|
673
691
|
module TrueClass
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
|
@@ -127,6 +127,24 @@ require 'json/common'
|
|
|
127
127
|
#
|
|
128
128
|
# ---
|
|
129
129
|
#
|
|
130
|
+
# Option +allow_duplicate_key+ specifies whether duplicate keys in objects
|
|
131
|
+
# should be ignored or cause an error to be raised:
|
|
132
|
+
#
|
|
133
|
+
# When not specified:
|
|
134
|
+
# # The last value is used and a deprecation warning emitted.
|
|
135
|
+
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
136
|
+
# # warning: detected duplicate keys in JSON object.
|
|
137
|
+
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
138
|
+
#
|
|
139
|
+
# When set to `+true+`
|
|
140
|
+
# # The last value is used.
|
|
141
|
+
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
142
|
+
#
|
|
143
|
+
# When set to `+false+`, the future default:
|
|
144
|
+
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
145
|
+
#
|
|
146
|
+
# ---
|
|
147
|
+
#
|
|
130
148
|
# Option +allow_nan+ (boolean) specifies whether to allow
|
|
131
149
|
# NaN, Infinity, and MinusInfinity in +source+;
|
|
132
150
|
# defaults to +false+.
|
|
@@ -143,8 +161,23 @@ require 'json/common'
|
|
|
143
161
|
# ruby = JSON.parse(source, {allow_nan: true})
|
|
144
162
|
# ruby # => [NaN, Infinity, -Infinity]
|
|
145
163
|
#
|
|
164
|
+
# ---
|
|
165
|
+
#
|
|
166
|
+
# Option +allow_trailing_comma+ (boolean) specifies whether to allow
|
|
167
|
+
# trailing commas in objects and arrays;
|
|
168
|
+
# defaults to +false+.
|
|
169
|
+
#
|
|
170
|
+
# With the default, +false+:
|
|
171
|
+
# JSON.parse('[1,]') # unexpected character: ']' at line 1 column 4 (JSON::ParserError)
|
|
172
|
+
#
|
|
173
|
+
# When enabled:
|
|
174
|
+
# JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
|
|
175
|
+
#
|
|
146
176
|
# ====== Output Options
|
|
147
177
|
#
|
|
178
|
+
# Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
|
|
179
|
+
# defaults to +false+.
|
|
180
|
+
#
|
|
148
181
|
# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys
|
|
149
182
|
# should be Symbols;
|
|
150
183
|
# defaults to +false+ (use Strings).
|
|
@@ -274,6 +307,25 @@ require 'json/common'
|
|
|
274
307
|
#
|
|
275
308
|
# ---
|
|
276
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
|
+
#
|
|
277
329
|
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth
|
|
278
330
|
# in +obj+; defaults to +100+.
|
|
279
331
|
#
|
|
@@ -351,6 +403,9 @@ require 'json/common'
|
|
|
351
403
|
#
|
|
352
404
|
# == \JSON Additions
|
|
353
405
|
#
|
|
406
|
+
# Note that JSON Additions must only be used with trusted data, and is
|
|
407
|
+
# deprecated.
|
|
408
|
+
#
|
|
354
409
|
# When you "round trip" a non-\String object from Ruby to \JSON and back,
|
|
355
410
|
# you have a new \String, instead of the object you began with:
|
|
356
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.15.1
|
|
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
|
|
@@ -28,6 +28,10 @@ files:
|
|
|
28
28
|
- ext/json/ext/generator/generator.c
|
|
29
29
|
- ext/json/ext/parser/extconf.rb
|
|
30
30
|
- ext/json/ext/parser/parser.c
|
|
31
|
+
- ext/json/ext/simd/conf.rb
|
|
32
|
+
- ext/json/ext/simd/simd.h
|
|
33
|
+
- ext/json/ext/vendor/fpconv.c
|
|
34
|
+
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
31
35
|
- json.gemspec
|
|
32
36
|
- lib/json.rb
|
|
33
37
|
- lib/json/add/bigdecimal.rb
|
|
@@ -41,6 +45,7 @@ files:
|
|
|
41
45
|
- lib/json/add/rational.rb
|
|
42
46
|
- lib/json/add/regexp.rb
|
|
43
47
|
- lib/json/add/set.rb
|
|
48
|
+
- lib/json/add/string.rb
|
|
44
49
|
- lib/json/add/struct.rb
|
|
45
50
|
- lib/json/add/symbol.rb
|
|
46
51
|
- lib/json/add/time.rb
|
|
@@ -77,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
82
|
- !ruby/object:Gem::Version
|
|
78
83
|
version: '0'
|
|
79
84
|
requirements: []
|
|
80
|
-
rubygems_version: 3.6.
|
|
85
|
+
rubygems_version: 3.6.9
|
|
81
86
|
specification_version: 4
|
|
82
87
|
summary: JSON Implementation for Ruby
|
|
83
88
|
test_files: []
|