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.
- checksums.yaml +4 -4
- data/CHANGES.md +205 -7
- data/LEGAL +12 -0
- data/README.md +43 -1
- data/ext/json/ext/fbuffer/fbuffer.h +140 -86
- data/ext/json/ext/generator/extconf.rb +8 -0
- data/ext/json/ext/generator/generator.c +787 -616
- data/ext/json/ext/json.h +116 -0
- data/ext/json/ext/parser/extconf.rb +11 -3
- data/ext/json/ext/parser/parser.c +974 -703
- data/ext/json/ext/simd/conf.rb +24 -0
- data/ext/json/ext/simd/simd.h +208 -0
- data/ext/json/ext/vendor/fpconv.c +480 -0
- data/ext/json/ext/vendor/jeaiii-ltoa.h +267 -0
- data/ext/json/ext/vendor/ryu.h +819 -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 +374 -188
- data/lib/json/ext/generator/state.rb +11 -14
- data/lib/json/ext.rb +2 -2
- data/lib/json/generic_object.rb +0 -8
- data/lib/json/truffle_ruby/generator.rb +137 -72
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +90 -2
- metadata +66 -57
|
@@ -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}[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 =
|
|
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,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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
293
|
-
result[
|
|
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
|
-
|
|
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
|
-
|
|
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? && !(
|
|
484
|
+
if state.strict? && !Generator.native_type?(value)
|
|
428
485
|
if state.as_json
|
|
429
|
-
value = state.as_json.call(value)
|
|
430
|
-
unless
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
487
|
-
if state.strict? && !(
|
|
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
|
|
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
|
|
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? && !(
|
|
631
|
+
if state.strict? && !Generator.native_type?(value)
|
|
549
632
|
if state.as_json
|
|
550
|
-
value = state.as_json.call(value)
|
|
551
|
-
unless
|
|
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
|
|
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
|
-
|
|
623
|
-
|
|
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
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::
|
|
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)
|