json 2.15.1 → 2.18.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 +35 -0
- data/LEGAL +12 -0
- data/README.md +17 -1
- data/ext/json/ext/fbuffer/fbuffer.h +9 -58
- data/ext/json/ext/generator/extconf.rb +1 -1
- data/ext/json/ext/generator/generator.c +192 -159
- data/ext/json/ext/json.h +97 -0
- data/ext/json/ext/parser/extconf.rb +2 -1
- data/ext/json/ext/parser/parser.c +519 -397
- data/ext/json/ext/simd/simd.h +15 -12
- data/ext/json/ext/vendor/fpconv.c +2 -2
- data/ext/json/ext/vendor/ryu.h +819 -0
- data/lib/json/common.rb +28 -16
- data/lib/json/ext/generator/state.rb +4 -0
- data/lib/json/truffle_ruby/generator.rb +53 -21
- data/lib/json/version.rb +1 -1
- metadata +3 -1
data/lib/json/common.rb
CHANGED
|
@@ -71,8 +71,13 @@ module JSON
|
|
|
71
71
|
end
|
|
72
72
|
when object_class
|
|
73
73
|
if opts[:create_additions] != false
|
|
74
|
-
if
|
|
75
|
-
klass =
|
|
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
|
+
|
|
76
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)
|
|
@@ -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
|
|
@@ -555,6 +550,7 @@ module JSON
|
|
|
555
550
|
:create_additions => nil,
|
|
556
551
|
}
|
|
557
552
|
# :call-seq:
|
|
553
|
+
# JSON.unsafe_load(source, options = {}) -> object
|
|
558
554
|
# JSON.unsafe_load(source, proc = nil, options = {}) -> object
|
|
559
555
|
#
|
|
560
556
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
@@ -686,7 +682,12 @@ module JSON
|
|
|
686
682
|
#
|
|
687
683
|
def unsafe_load(source, proc = nil, options = nil)
|
|
688
684
|
opts = if options.nil?
|
|
689
|
-
|
|
685
|
+
if proc && proc.is_a?(Hash)
|
|
686
|
+
options, proc = proc, nil
|
|
687
|
+
options
|
|
688
|
+
else
|
|
689
|
+
_unsafe_load_default_options
|
|
690
|
+
end
|
|
690
691
|
else
|
|
691
692
|
_unsafe_load_default_options.merge(options)
|
|
692
693
|
end
|
|
@@ -714,6 +715,7 @@ module JSON
|
|
|
714
715
|
end
|
|
715
716
|
|
|
716
717
|
# :call-seq:
|
|
718
|
+
# JSON.load(source, options = {}) -> object
|
|
717
719
|
# JSON.load(source, proc = nil, options = {}) -> object
|
|
718
720
|
#
|
|
719
721
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
@@ -850,8 +852,18 @@ module JSON
|
|
|
850
852
|
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
|
851
853
|
#
|
|
852
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
|
+
|
|
853
860
|
opts = if options.nil?
|
|
854
|
-
|
|
861
|
+
if proc && proc.is_a?(Hash)
|
|
862
|
+
options, proc = proc, nil
|
|
863
|
+
options
|
|
864
|
+
else
|
|
865
|
+
_load_default_options
|
|
866
|
+
end
|
|
855
867
|
else
|
|
856
868
|
_load_default_options.merge(options)
|
|
857
869
|
end
|
|
@@ -1053,7 +1065,7 @@ module JSON
|
|
|
1053
1065
|
options[:as_json] = as_json if as_json
|
|
1054
1066
|
|
|
1055
1067
|
@state = State.new(options).freeze
|
|
1056
|
-
@parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options))
|
|
1068
|
+
@parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze
|
|
1057
1069
|
end
|
|
1058
1070
|
|
|
1059
1071
|
# call-seq:
|
|
@@ -1062,7 +1074,7 @@ module JSON
|
|
|
1062
1074
|
#
|
|
1063
1075
|
# Serialize the given object into a \JSON document.
|
|
1064
1076
|
def dump(object, io = nil)
|
|
1065
|
-
@state.
|
|
1077
|
+
@state.generate(object, io)
|
|
1066
1078
|
end
|
|
1067
1079
|
alias_method :generate, :dump
|
|
1068
1080
|
|
|
@@ -75,6 +75,8 @@ module JSON
|
|
|
75
75
|
#
|
|
76
76
|
# Returns the value returned by method +name+.
|
|
77
77
|
def [](name)
|
|
78
|
+
::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
|
|
79
|
+
|
|
78
80
|
if respond_to?(name)
|
|
79
81
|
__send__(name)
|
|
80
82
|
else
|
|
@@ -87,6 +89,8 @@ module JSON
|
|
|
87
89
|
#
|
|
88
90
|
# Sets the attribute name to value.
|
|
89
91
|
def []=(name, value)
|
|
92
|
+
::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
|
|
93
|
+
|
|
90
94
|
if respond_to?(name_writer = "#{name}=")
|
|
91
95
|
__send__ name_writer, value
|
|
92
96
|
else
|
|
@@ -55,6 +55,11 @@ module JSON
|
|
|
55
55
|
(Symbol === key || String === key)
|
|
56
56
|
end
|
|
57
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
|
+
|
|
58
63
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
|
59
64
|
# UTF16 big endian characters as \u????, and return it.
|
|
60
65
|
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
|
@@ -212,7 +217,7 @@ module JSON
|
|
|
212
217
|
return if @max_nesting.zero?
|
|
213
218
|
current_nesting = depth + 1
|
|
214
219
|
current_nesting > @max_nesting and
|
|
215
|
-
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?"
|
|
216
221
|
end
|
|
217
222
|
|
|
218
223
|
# Returns true, if circular data structures are checked,
|
|
@@ -307,8 +312,8 @@ module JSON
|
|
|
307
312
|
def to_h
|
|
308
313
|
result = {}
|
|
309
314
|
instance_variables.each do |iv|
|
|
310
|
-
|
|
311
|
-
result[
|
|
315
|
+
key = iv.to_s[1..-1]
|
|
316
|
+
result[key.to_sym] = instance_variable_get(iv)
|
|
312
317
|
end
|
|
313
318
|
|
|
314
319
|
if result[:allow_duplicate_key].nil?
|
|
@@ -325,6 +330,9 @@ module JSON
|
|
|
325
330
|
# created this method raises a
|
|
326
331
|
# GeneratorError exception.
|
|
327
332
|
def generate(obj, anIO = nil)
|
|
333
|
+
return dup.generate(obj, anIO) if frozen?
|
|
334
|
+
|
|
335
|
+
depth = @depth
|
|
328
336
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
329
337
|
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
|
330
338
|
result = generate_json(obj, ''.dup)
|
|
@@ -341,10 +349,8 @@ module JSON
|
|
|
341
349
|
else
|
|
342
350
|
result
|
|
343
351
|
end
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
def generate_new(obj, anIO = nil) # :nodoc:
|
|
347
|
-
dup.generate(obj, anIO)
|
|
352
|
+
ensure
|
|
353
|
+
@depth = depth unless frozen?
|
|
348
354
|
end
|
|
349
355
|
|
|
350
356
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
|
@@ -430,6 +436,8 @@ module JSON
|
|
|
430
436
|
|
|
431
437
|
# Return the value returned by method +name+.
|
|
432
438
|
def [](name)
|
|
439
|
+
::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
|
|
440
|
+
|
|
433
441
|
if respond_to?(name)
|
|
434
442
|
__send__(name)
|
|
435
443
|
else
|
|
@@ -439,6 +447,8 @@ module JSON
|
|
|
439
447
|
end
|
|
440
448
|
|
|
441
449
|
def []=(name, value)
|
|
450
|
+
::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
|
|
451
|
+
|
|
442
452
|
if respond_to?(name_writer = "#{name}=")
|
|
443
453
|
__send__ name_writer, value
|
|
444
454
|
else
|
|
@@ -481,17 +491,15 @@ module JSON
|
|
|
481
491
|
# _depth_ is used to find out nesting depth, to indent accordingly.
|
|
482
492
|
def to_json(state = nil, *)
|
|
483
493
|
state = State.from_state(state)
|
|
494
|
+
depth = state.depth
|
|
484
495
|
state.check_max_nesting
|
|
485
496
|
json_transform(state)
|
|
497
|
+
ensure
|
|
498
|
+
state.depth = depth
|
|
486
499
|
end
|
|
487
500
|
|
|
488
501
|
private
|
|
489
502
|
|
|
490
|
-
def json_shift(state)
|
|
491
|
-
state.object_nl.empty? or return ''
|
|
492
|
-
state.indent * state.depth
|
|
493
|
-
end
|
|
494
|
-
|
|
495
503
|
def json_transform(state)
|
|
496
504
|
depth = state.depth += 1
|
|
497
505
|
|
|
@@ -517,13 +525,17 @@ module JSON
|
|
|
517
525
|
end
|
|
518
526
|
result << state.indent * depth if indent
|
|
519
527
|
|
|
520
|
-
if state.strict?
|
|
521
|
-
if state.as_json
|
|
528
|
+
if state.strict?
|
|
529
|
+
if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
|
|
522
530
|
key = state.as_json.call(key, true)
|
|
523
531
|
end
|
|
524
532
|
|
|
525
533
|
unless Generator.native_key?(key)
|
|
526
|
-
raise GeneratorError.new("#{key.class} not allowed as object key in JSON",
|
|
534
|
+
raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
unless Generator.valid_encoding?(key)
|
|
538
|
+
raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
|
|
527
539
|
end
|
|
528
540
|
end
|
|
529
541
|
|
|
@@ -542,17 +554,19 @@ module JSON
|
|
|
542
554
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
543
555
|
end
|
|
544
556
|
result << value.to_json(state)
|
|
557
|
+
state.depth = depth
|
|
545
558
|
else
|
|
546
559
|
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
|
547
560
|
end
|
|
548
561
|
elsif value.respond_to?(:to_json)
|
|
549
562
|
result << value.to_json(state)
|
|
563
|
+
state.depth = depth
|
|
550
564
|
else
|
|
551
565
|
result << %{"#{String(value)}"}
|
|
552
566
|
end
|
|
553
567
|
first = false
|
|
554
568
|
}
|
|
555
|
-
depth
|
|
569
|
+
depth -= 1
|
|
556
570
|
unless first
|
|
557
571
|
result << state.object_nl
|
|
558
572
|
result << state.indent * depth if indent
|
|
@@ -569,8 +583,11 @@ module JSON
|
|
|
569
583
|
# produced JSON string output further.
|
|
570
584
|
def to_json(state = nil, *)
|
|
571
585
|
state = State.from_state(state)
|
|
586
|
+
depth = state.depth
|
|
572
587
|
state.check_max_nesting
|
|
573
588
|
json_transform(state)
|
|
589
|
+
ensure
|
|
590
|
+
state.depth = depth
|
|
574
591
|
end
|
|
575
592
|
|
|
576
593
|
private
|
|
@@ -608,12 +625,13 @@ module JSON
|
|
|
608
625
|
end
|
|
609
626
|
elsif value.respond_to?(:to_json)
|
|
610
627
|
result << value.to_json(state)
|
|
628
|
+
state.depth = depth
|
|
611
629
|
else
|
|
612
630
|
result << %{"#{String(value)}"}
|
|
613
631
|
end
|
|
614
632
|
first = false
|
|
615
633
|
}
|
|
616
|
-
depth
|
|
634
|
+
depth -= 1
|
|
617
635
|
result << state.array_nl
|
|
618
636
|
result << state.indent * depth if indent
|
|
619
637
|
result << ']'
|
|
@@ -638,6 +656,9 @@ module JSON
|
|
|
638
656
|
if casted_value.equal?(self)
|
|
639
657
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
640
658
|
end
|
|
659
|
+
unless Generator.native_type?(casted_value)
|
|
660
|
+
raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
|
|
661
|
+
end
|
|
641
662
|
|
|
642
663
|
state.check_max_nesting
|
|
643
664
|
state.depth += 1
|
|
@@ -670,14 +691,25 @@ module JSON
|
|
|
670
691
|
# \u????.
|
|
671
692
|
def to_json(state = nil, *args)
|
|
672
693
|
state = State.from_state(state)
|
|
673
|
-
|
|
674
|
-
|
|
694
|
+
string = self
|
|
695
|
+
|
|
696
|
+
if state.strict? && state.as_json
|
|
697
|
+
unless Generator.valid_encoding?(string)
|
|
698
|
+
string = state.as_json.call(string, false)
|
|
699
|
+
unless string.is_a?(::String)
|
|
700
|
+
return string.to_json(state, *args)
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
|
|
705
|
+
if string.encoding == ::Encoding::UTF_8
|
|
706
|
+
unless string.valid_encoding?
|
|
675
707
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
|
|
676
708
|
end
|
|
677
|
-
string = self
|
|
678
709
|
else
|
|
679
|
-
string = encode(::Encoding::UTF_8)
|
|
710
|
+
string = string.encode(::Encoding::UTF_8)
|
|
680
711
|
end
|
|
712
|
+
|
|
681
713
|
if state.ascii_only?
|
|
682
714
|
%("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
|
|
683
715
|
else
|
data/lib/json/version.rb
CHANGED
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.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -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
|