json 2.19.5 → 2.21.2
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 +48 -0
- data/LEGAL +3 -3
- data/README.md +16 -7
- data/ext/json/ext/fbuffer/fbuffer.h +32 -24
- data/ext/json/ext/generator/extconf.rb +1 -0
- data/ext/json/ext/generator/generator.c +92 -18
- data/ext/json/ext/json.h +67 -0
- data/ext/json/ext/parser/extconf.rb +23 -0
- data/ext/json/ext/parser/parser.c +1563 -354
- data/ext/json/ext/vendor/fast_float_parser.h +814 -0
- data/lib/json/common.rb +9 -0
- data/lib/json/ext/generator/state.rb +1 -0
- data/lib/json/ext.rb +26 -0
- data/lib/json/truffle_ruby/generator.rb +39 -1
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +34 -5
- metadata +3 -3
- data/ext/json/ext/vendor/ryu.h +0 -819
data/lib/json/common.rb
CHANGED
|
@@ -155,6 +155,15 @@ module JSON
|
|
|
155
155
|
# Set the module _generator_ to be used by JSON.
|
|
156
156
|
def generator=(generator) # :nodoc:
|
|
157
157
|
old, $VERBOSE = $VERBOSE, nil
|
|
158
|
+
|
|
159
|
+
# The default proc used when the +sort_keys+ generation option is +true+.
|
|
160
|
+
# It returns a new hash with the entries sorted by their keys.
|
|
161
|
+
sort_keys_proc = ->(hash) { hash.sort.to_h }
|
|
162
|
+
if defined?(::Ractor) && Ractor.respond_to?(:shareable_lambda)
|
|
163
|
+
sort_keys_proc = Ractor.shareable_lambda(&sort_keys_proc)
|
|
164
|
+
end
|
|
165
|
+
generator::State.default_sort_keys_proc = sort_keys_proc
|
|
166
|
+
|
|
158
167
|
@generator = generator
|
|
159
168
|
if generator.const_defined?(:GeneratorMethods)
|
|
160
169
|
generator_methods = generator::GeneratorMethods
|
data/lib/json/ext.rb
CHANGED
|
@@ -41,5 +41,31 @@ module JSON
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
if defined?(ResumableParser) # Not yet available on JRuby
|
|
45
|
+
class ResumableParser
|
|
46
|
+
# Returns whether the parser is entirely done: no unconsumed bytes in
|
|
47
|
+
# the buffer, no document under construction and no parsed value
|
|
48
|
+
# awaiting retrieval.
|
|
49
|
+
#
|
|
50
|
+
# The main use case is detecting a truncated stream once the input is
|
|
51
|
+
# exhausted:
|
|
52
|
+
#
|
|
53
|
+
# loop do
|
|
54
|
+
# begin
|
|
55
|
+
# parser << socket.readpartial(4096)
|
|
56
|
+
# rescue EOFError
|
|
57
|
+
# break
|
|
58
|
+
# end
|
|
59
|
+
# while parser.parse
|
|
60
|
+
# process(parser.value)
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
# warn "stream was truncated" unless parser.empty?
|
|
64
|
+
def empty?
|
|
65
|
+
eos? && !partial_value? && !value?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
44
70
|
JSON_LOADED = true unless defined?(JSON::JSON_LOADED)
|
|
45
71
|
end
|
|
@@ -111,6 +111,8 @@ module JSON
|
|
|
111
111
|
# This class is used to create State instances, that are use to hold data
|
|
112
112
|
# while generating a JSON text from a Ruby data structure.
|
|
113
113
|
class State
|
|
114
|
+
singleton_class.attr_accessor :default_sort_keys_proc # :nodoc:
|
|
115
|
+
|
|
114
116
|
def self.generate(obj, opts = nil, io = nil)
|
|
115
117
|
new(opts).generate(obj, io)
|
|
116
118
|
end
|
|
@@ -164,6 +166,7 @@ module JSON
|
|
|
164
166
|
@script_safe = false
|
|
165
167
|
@strict = false
|
|
166
168
|
@max_nesting = 100
|
|
169
|
+
@sort_keys = false
|
|
167
170
|
configure(opts) if opts
|
|
168
171
|
end
|
|
169
172
|
|
|
@@ -199,6 +202,33 @@ module JSON
|
|
|
199
202
|
# supported by the JSON spec will raise a JSON::GeneratorError
|
|
200
203
|
attr_accessor :strict
|
|
201
204
|
|
|
205
|
+
# Controls key sorting in the generated JSON. If set to +true+, object
|
|
206
|
+
# keys are sorted by key lexicographically. If set to a Proc, it
|
|
207
|
+
# receives the entire Hash and must return a Hash with its pairs in the
|
|
208
|
+
# desired order.
|
|
209
|
+
attr_reader :sort_keys
|
|
210
|
+
|
|
211
|
+
def sort_keys=(value) # :nodoc:
|
|
212
|
+
type_error = false
|
|
213
|
+
@sort_keys = case value
|
|
214
|
+
when Proc
|
|
215
|
+
value
|
|
216
|
+
when true
|
|
217
|
+
State.default_sort_keys_proc
|
|
218
|
+
when nil, false
|
|
219
|
+
false
|
|
220
|
+
else
|
|
221
|
+
type_error = true
|
|
222
|
+
false
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
if type_error
|
|
226
|
+
raise TypeError, "The `sort_keys` argument must be a boolean or a Proc"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
@sort_keys
|
|
230
|
+
end
|
|
231
|
+
|
|
202
232
|
# :stopdoc:
|
|
203
233
|
attr_reader :buffer_initial_length
|
|
204
234
|
|
|
@@ -285,6 +315,7 @@ module JSON
|
|
|
285
315
|
@allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
|
|
286
316
|
@as_json = opts[:as_json].to_proc if opts[:as_json]
|
|
287
317
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
|
318
|
+
self.sort_keys = opts[:sort_keys] if opts.key?(:sort_keys)
|
|
288
319
|
@depth = opts[:depth] || 0
|
|
289
320
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
|
290
321
|
|
|
@@ -307,6 +338,9 @@ module JSON
|
|
|
307
338
|
if !opts.key?(:max_nesting) # defaults to 100
|
|
308
339
|
@max_nesting = 100
|
|
309
340
|
elsif opts[:max_nesting]
|
|
341
|
+
unless opts[:max_nesting].is_a?(Integer)
|
|
342
|
+
raise TypeError, ":max_nesting must be an Integer, got: #{opts[:max_nesting].class}"
|
|
343
|
+
end
|
|
310
344
|
@max_nesting = opts[:max_nesting]
|
|
311
345
|
else
|
|
312
346
|
@max_nesting = 0
|
|
@@ -346,9 +380,13 @@ module JSON
|
|
|
346
380
|
|
|
347
381
|
depth = @depth
|
|
348
382
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
349
|
-
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
|
383
|
+
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) and !@sort_keys
|
|
350
384
|
result = generate_json(obj, ''.dup)
|
|
351
385
|
else
|
|
386
|
+
if @sort_keys
|
|
387
|
+
obj = @sort_keys.call(obj)
|
|
388
|
+
end
|
|
389
|
+
|
|
352
390
|
result = obj.to_json(self)
|
|
353
391
|
end
|
|
354
392
|
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
|
@@ -121,9 +121,11 @@ require 'json/common'
|
|
|
121
121
|
# ====== Input Options
|
|
122
122
|
#
|
|
123
123
|
# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed;
|
|
124
|
-
# defaults to +100+;
|
|
124
|
+
# defaults to +100+;
|
|
125
|
+
# You can set it to +false+ to disable depth checking entirely, but that is dangerous
|
|
126
|
+
# when parsing untrusted input.
|
|
125
127
|
#
|
|
126
|
-
# With the default, +
|
|
128
|
+
# With the default, +100+:
|
|
127
129
|
# source = '[0, [1, [2, [3]]]]'
|
|
128
130
|
# ruby = JSON.parse(source)
|
|
129
131
|
# ruby # => [0, [1, [2, [3]]]]
|
|
@@ -145,11 +147,11 @@ require 'json/common'
|
|
|
145
147
|
# # warning: detected duplicate keys in JSON object.
|
|
146
148
|
# # This will raise an error in json 3.0 unless enabled via `allow_duplicate_key: true`
|
|
147
149
|
#
|
|
148
|
-
# When set to
|
|
150
|
+
# When set to +true+:
|
|
149
151
|
# # The last value is used.
|
|
150
152
|
# JSON.parse('{"a": 1, "a":2}') => {"a" => 2}
|
|
151
153
|
#
|
|
152
|
-
# When set to
|
|
154
|
+
# When set to +false+, the future default:
|
|
153
155
|
# JSON.parse('{"a": 1, "a":2}') => duplicate key at line 1 column 1 (JSON::ParserError)
|
|
154
156
|
#
|
|
155
157
|
# ---
|
|
@@ -184,6 +186,20 @@ require 'json/common'
|
|
|
184
186
|
#
|
|
185
187
|
# ---
|
|
186
188
|
#
|
|
189
|
+
# Option +allow_comments+ (boolean) specifies whether to allow
|
|
190
|
+
# JavaScript style comments (either <tt>// comment</tt> or <tt>/* comment */</tt>);
|
|
191
|
+
# defaults to +false+.
|
|
192
|
+
#
|
|
193
|
+
# When not specified, a deprecation warning is emitted if a comment is encountered.
|
|
194
|
+
#
|
|
195
|
+
# When set to +true+, comments are ignored:
|
|
196
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2}') # => {"a" => 2}
|
|
197
|
+
#
|
|
198
|
+
# When set to +false+, the future default:
|
|
199
|
+
# JSON.parse('/* comment */ {"a": 1, "a":2}') # unexpected character: '/' at line 1 column 1 (JSON::ParserError)
|
|
200
|
+
#
|
|
201
|
+
# ---
|
|
202
|
+
#
|
|
187
203
|
# Option +allow_control_characters+ (boolean) specifies whether to allow
|
|
188
204
|
# unescaped ASCII control characters, such as newlines, in strings;
|
|
189
205
|
# defaults to +false+.
|
|
@@ -370,6 +386,15 @@ require 'json/common'
|
|
|
370
386
|
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
|
371
387
|
# JSON.generate(obj, max_nesting: 2)
|
|
372
388
|
#
|
|
389
|
+
# With +false+:
|
|
390
|
+
# obj = []
|
|
391
|
+
# obj[0] = obj
|
|
392
|
+
# # Raises SystemStackError: stack level too deep
|
|
393
|
+
# JSON.generate(obj, max_nesting: false)
|
|
394
|
+
#
|
|
395
|
+
# Setting +max_nesting+ to +false+ can lead to a stackoverflow and may leave the program
|
|
396
|
+
# in an unrecoverable state. It is discouraged.
|
|
397
|
+
#
|
|
373
398
|
# ====== Escaping Options
|
|
374
399
|
#
|
|
375
400
|
# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt>
|
|
@@ -394,7 +419,6 @@ require 'json/common'
|
|
|
394
419
|
# to be inserted after each \JSON object; defaults to the empty \String, <tt>''</tt>.
|
|
395
420
|
# - Option +indent+ (\String) specifies the string (usually spaces) to be
|
|
396
421
|
# used for indentation; defaults to the empty \String, <tt>''</tt>;
|
|
397
|
-
# defaults to the empty \String, <tt>''</tt>;
|
|
398
422
|
# has no effect unless options +array_nl+ or +object_nl+ specify newlines.
|
|
399
423
|
# - Option +space+ (\String) specifies a string (usually a space) to be
|
|
400
424
|
# inserted after the colon in each \JSON object's pair;
|
|
@@ -402,6 +426,11 @@ require 'json/common'
|
|
|
402
426
|
# - Option +space_before+ (\String) specifies a string (usually a space) to be
|
|
403
427
|
# inserted before the colon in each \JSON object's pair;
|
|
404
428
|
# defaults to the empty \String, <tt>''</tt>.
|
|
429
|
+
# - Option +sort_keys+ (boolean or \Proc) controls whether and how the keys of a
|
|
430
|
+
# hash are sorted when generating the output; defaults to <tt>false</tt>.
|
|
431
|
+
# When +true+, keys are sorted lexicographically. When a \Proc, it receives
|
|
432
|
+
# the entire \Hash and must return a \Hash with its pairs in the desired
|
|
433
|
+
# order, allowing for arbitrary sort orders.
|
|
405
434
|
#
|
|
406
435
|
# In this example, +obj+ is used first to generate the shortest
|
|
407
436
|
# \JSON data (no whitespace), then again with all formatting options
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.21.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -31,9 +31,9 @@ files:
|
|
|
31
31
|
- ext/json/ext/parser/parser.c
|
|
32
32
|
- ext/json/ext/simd/conf.rb
|
|
33
33
|
- ext/json/ext/simd/simd.h
|
|
34
|
+
- ext/json/ext/vendor/fast_float_parser.h
|
|
34
35
|
- ext/json/ext/vendor/fpconv.c
|
|
35
36
|
- ext/json/ext/vendor/jeaiii-ltoa.h
|
|
36
|
-
- ext/json/ext/vendor/ryu.h
|
|
37
37
|
- json.gemspec
|
|
38
38
|
- lib/json.rb
|
|
39
39
|
- lib/json/add/bigdecimal.rb
|
|
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
85
|
version: '0'
|
|
86
86
|
requirements: []
|
|
87
|
-
rubygems_version: 4.0.
|
|
87
|
+
rubygems_version: 4.0.16
|
|
88
88
|
specification_version: 4
|
|
89
89
|
summary: JSON Implementation for Ruby
|
|
90
90
|
test_files: []
|