json 2.14.1 → 2.19.3
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 +68 -1
- data/LEGAL +12 -0
- data/README.md +19 -1
- data/ext/json/ext/fbuffer/fbuffer.h +32 -77
- data/ext/json/ext/generator/extconf.rb +1 -1
- data/ext/json/ext/generator/generator.c +295 -471
- data/ext/json/ext/json.h +105 -0
- data/ext/json/ext/parser/extconf.rb +2 -1
- data/ext/json/ext/parser/parser.c +617 -477
- data/ext/json/ext/simd/simd.h +42 -22
- data/ext/json/ext/vendor/fpconv.c +13 -12
- data/ext/json/ext/vendor/ryu.h +819 -0
- data/lib/json/common.rb +69 -26
- data/lib/json/ext/generator/state.rb +5 -1
- data/lib/json/truffle_ruby/generator.rb +86 -34
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +33 -0
- metadata +4 -2
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,29 +152,21 @@ 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
|
|
163
158
|
@generator = generator
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
if generator.const_defined?(:GeneratorMethods)
|
|
160
|
+
generator_methods = generator::GeneratorMethods
|
|
161
|
+
for const in generator_methods.constants
|
|
162
|
+
klass = const_get(const)
|
|
163
|
+
modul = generator_methods.const_get(const)
|
|
164
|
+
klass.class_eval do
|
|
165
|
+
instance_methods(false).each do |m|
|
|
166
|
+
m.to_s == 'to_json' and remove_method m
|
|
167
|
+
end
|
|
168
|
+
include modul
|
|
171
169
|
end
|
|
172
|
-
include modul
|
|
173
170
|
end
|
|
174
171
|
end
|
|
175
172
|
self.state = generator::State
|
|
@@ -555,6 +552,7 @@ module JSON
|
|
|
555
552
|
:create_additions => nil,
|
|
556
553
|
}
|
|
557
554
|
# :call-seq:
|
|
555
|
+
# JSON.unsafe_load(source, options = {}) -> object
|
|
558
556
|
# JSON.unsafe_load(source, proc = nil, options = {}) -> object
|
|
559
557
|
#
|
|
560
558
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
@@ -686,7 +684,12 @@ module JSON
|
|
|
686
684
|
#
|
|
687
685
|
def unsafe_load(source, proc = nil, options = nil)
|
|
688
686
|
opts = if options.nil?
|
|
689
|
-
|
|
687
|
+
if proc && proc.is_a?(Hash)
|
|
688
|
+
options, proc = proc, nil
|
|
689
|
+
options
|
|
690
|
+
else
|
|
691
|
+
_unsafe_load_default_options
|
|
692
|
+
end
|
|
690
693
|
else
|
|
691
694
|
_unsafe_load_default_options.merge(options)
|
|
692
695
|
end
|
|
@@ -714,6 +717,7 @@ module JSON
|
|
|
714
717
|
end
|
|
715
718
|
|
|
716
719
|
# :call-seq:
|
|
720
|
+
# JSON.load(source, options = {}) -> object
|
|
717
721
|
# JSON.load(source, proc = nil, options = {}) -> object
|
|
718
722
|
#
|
|
719
723
|
# Returns the Ruby objects created by parsing the given +source+.
|
|
@@ -850,8 +854,18 @@ module JSON
|
|
|
850
854
|
# @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}
|
|
851
855
|
#
|
|
852
856
|
def load(source, proc = nil, options = nil)
|
|
857
|
+
if proc && options.nil? && proc.is_a?(Hash)
|
|
858
|
+
options = proc
|
|
859
|
+
proc = nil
|
|
860
|
+
end
|
|
861
|
+
|
|
853
862
|
opts = if options.nil?
|
|
854
|
-
|
|
863
|
+
if proc && proc.is_a?(Hash)
|
|
864
|
+
options, proc = proc, nil
|
|
865
|
+
options
|
|
866
|
+
else
|
|
867
|
+
_load_default_options
|
|
868
|
+
end
|
|
855
869
|
else
|
|
856
870
|
_load_default_options.merge(options)
|
|
857
871
|
end
|
|
@@ -866,7 +880,7 @@ module JSON
|
|
|
866
880
|
end
|
|
867
881
|
end
|
|
868
882
|
|
|
869
|
-
if opts[:allow_blank] && (source.nil? || source.empty?)
|
|
883
|
+
if opts[:allow_blank] && (source.nil? || (String === source && source.empty?))
|
|
870
884
|
source = 'null'
|
|
871
885
|
end
|
|
872
886
|
|
|
@@ -1024,7 +1038,8 @@ module JSON
|
|
|
1024
1038
|
# JSON.new(options = nil, &block)
|
|
1025
1039
|
#
|
|
1026
1040
|
# Argument +options+, if given, contains a \Hash of options for both parsing and generating.
|
|
1027
|
-
# See {Parsing Options}[
|
|
1041
|
+
# See {Parsing Options}[rdoc-ref:JSON@Parsing+Options],
|
|
1042
|
+
# and {Generating Options}[rdoc-ref:JSON@Generating+Options].
|
|
1028
1043
|
#
|
|
1029
1044
|
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
|
1030
1045
|
# encountered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
|
@@ -1053,7 +1068,7 @@ module JSON
|
|
|
1053
1068
|
options[:as_json] = as_json if as_json
|
|
1054
1069
|
|
|
1055
1070
|
@state = State.new(options).freeze
|
|
1056
|
-
@parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options))
|
|
1071
|
+
@parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)).freeze
|
|
1057
1072
|
end
|
|
1058
1073
|
|
|
1059
1074
|
# call-seq:
|
|
@@ -1062,7 +1077,7 @@ module JSON
|
|
|
1062
1077
|
#
|
|
1063
1078
|
# Serialize the given object into a \JSON document.
|
|
1064
1079
|
def dump(object, io = nil)
|
|
1065
|
-
@state.
|
|
1080
|
+
@state.generate(object, io)
|
|
1066
1081
|
end
|
|
1067
1082
|
alias_method :generate, :dump
|
|
1068
1083
|
|
|
@@ -1083,6 +1098,30 @@ module JSON
|
|
|
1083
1098
|
load(File.read(path, encoding: Encoding::UTF_8))
|
|
1084
1099
|
end
|
|
1085
1100
|
end
|
|
1101
|
+
|
|
1102
|
+
module GeneratorMethods
|
|
1103
|
+
# call-seq: to_json(*)
|
|
1104
|
+
#
|
|
1105
|
+
# Converts this object into a JSON string.
|
|
1106
|
+
# If this object doesn't directly maps to a JSON native type,
|
|
1107
|
+
# first convert it to a string (calling #to_s), then converts
|
|
1108
|
+
# it to a JSON string, and returns the result.
|
|
1109
|
+
# This is a fallback, if no special method #to_json was defined for some object.
|
|
1110
|
+
def to_json(state = nil, *)
|
|
1111
|
+
obj = case self
|
|
1112
|
+
when nil, false, true, Integer, Float, Array, Hash
|
|
1113
|
+
self
|
|
1114
|
+
else
|
|
1115
|
+
"#{self}"
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
if state.nil?
|
|
1119
|
+
JSON::State._generate_no_fallback(obj, nil, nil)
|
|
1120
|
+
else
|
|
1121
|
+
JSON::State.from_state(state)._generate_no_fallback(obj)
|
|
1122
|
+
end
|
|
1123
|
+
end
|
|
1124
|
+
end
|
|
1086
1125
|
end
|
|
1087
1126
|
|
|
1088
1127
|
module ::Kernel
|
|
@@ -1128,3 +1167,7 @@ module ::Kernel
|
|
|
1128
1167
|
JSON[object, opts]
|
|
1129
1168
|
end
|
|
1130
1169
|
end
|
|
1170
|
+
|
|
1171
|
+
class Object
|
|
1172
|
+
include JSON::GeneratorMethods
|
|
1173
|
+
end
|
|
@@ -9,7 +9,7 @@ module JSON
|
|
|
9
9
|
# Instantiates a new State object, configured by _opts_.
|
|
10
10
|
#
|
|
11
11
|
# Argument +opts+, if given, contains a \Hash of options for the generation.
|
|
12
|
-
# See {Generating Options}[
|
|
12
|
+
# See {Generating Options}[rdoc-ref:JSON@Generating+Options].
|
|
13
13
|
def initialize(opts = nil)
|
|
14
14
|
if opts && !opts.empty?
|
|
15
15
|
configure(opts)
|
|
@@ -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
|
|
@@ -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:
|
|
@@ -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
|
|
@@ -299,8 +324,8 @@ module JSON
|
|
|
299
324
|
def to_h
|
|
300
325
|
result = {}
|
|
301
326
|
instance_variables.each do |iv|
|
|
302
|
-
|
|
303
|
-
result[
|
|
327
|
+
key = iv.to_s[1..-1]
|
|
328
|
+
result[key.to_sym] = instance_variable_get(iv)
|
|
304
329
|
end
|
|
305
330
|
|
|
306
331
|
if result[:allow_duplicate_key].nil?
|
|
@@ -317,6 +342,9 @@ module JSON
|
|
|
317
342
|
# created this method raises a
|
|
318
343
|
# GeneratorError exception.
|
|
319
344
|
def generate(obj, anIO = nil)
|
|
345
|
+
return dup.generate(obj, anIO) if frozen?
|
|
346
|
+
|
|
347
|
+
depth = @depth
|
|
320
348
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
|
321
349
|
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
|
322
350
|
result = generate_json(obj, ''.dup)
|
|
@@ -333,10 +361,8 @@ module JSON
|
|
|
333
361
|
else
|
|
334
362
|
result
|
|
335
363
|
end
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
def generate_new(obj, anIO = nil) # :nodoc:
|
|
339
|
-
dup.generate(obj, anIO)
|
|
364
|
+
ensure
|
|
365
|
+
@depth = depth unless frozen?
|
|
340
366
|
end
|
|
341
367
|
|
|
342
368
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
|
@@ -422,6 +448,8 @@ module JSON
|
|
|
422
448
|
|
|
423
449
|
# Return the value returned by method +name+.
|
|
424
450
|
def [](name)
|
|
451
|
+
::JSON.deprecation_warning("JSON::State#[] is deprecated and will be removed in json 3.0.0")
|
|
452
|
+
|
|
425
453
|
if respond_to?(name)
|
|
426
454
|
__send__(name)
|
|
427
455
|
else
|
|
@@ -431,6 +459,8 @@ module JSON
|
|
|
431
459
|
end
|
|
432
460
|
|
|
433
461
|
def []=(name, value)
|
|
462
|
+
::JSON.deprecation_warning("JSON::State#[]= is deprecated and will be removed in json 3.0.0")
|
|
463
|
+
|
|
434
464
|
if respond_to?(name_writer = "#{name}=")
|
|
435
465
|
__send__ name_writer, value
|
|
436
466
|
else
|
|
@@ -448,10 +478,10 @@ module JSON
|
|
|
448
478
|
state = State.from_state(state) if state
|
|
449
479
|
if state&.strict?
|
|
450
480
|
value = self
|
|
451
|
-
if state.strict? && !(
|
|
481
|
+
if state.strict? && !Generator.native_type?(value)
|
|
452
482
|
if state.as_json
|
|
453
|
-
value = state.as_json.call(value)
|
|
454
|
-
unless
|
|
483
|
+
value = state.as_json.call(value, false)
|
|
484
|
+
unless Generator.native_type?(value)
|
|
455
485
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
456
486
|
end
|
|
457
487
|
value.to_json(state)
|
|
@@ -473,17 +503,15 @@ module JSON
|
|
|
473
503
|
# _depth_ is used to find out nesting depth, to indent accordingly.
|
|
474
504
|
def to_json(state = nil, *)
|
|
475
505
|
state = State.from_state(state)
|
|
506
|
+
depth = state.depth
|
|
476
507
|
state.check_max_nesting
|
|
477
508
|
json_transform(state)
|
|
509
|
+
ensure
|
|
510
|
+
state.depth = depth
|
|
478
511
|
end
|
|
479
512
|
|
|
480
513
|
private
|
|
481
514
|
|
|
482
|
-
def json_shift(state)
|
|
483
|
-
state.object_nl.empty? or return ''
|
|
484
|
-
state.indent * state.depth
|
|
485
|
-
end
|
|
486
|
-
|
|
487
515
|
def json_transform(state)
|
|
488
516
|
depth = state.depth += 1
|
|
489
517
|
|
|
@@ -509,13 +537,17 @@ module JSON
|
|
|
509
537
|
end
|
|
510
538
|
result << state.indent * depth if indent
|
|
511
539
|
|
|
512
|
-
if state.strict?
|
|
513
|
-
if state.as_json
|
|
514
|
-
key = state.as_json.call(key)
|
|
540
|
+
if state.strict?
|
|
541
|
+
if state.as_json && (!Generator.native_key?(key) || !Generator.valid_encoding?(key))
|
|
542
|
+
key = state.as_json.call(key, true)
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
unless Generator.native_key?(key)
|
|
546
|
+
raise GeneratorError.new("#{key.class} not allowed as object key in JSON", key)
|
|
515
547
|
end
|
|
516
548
|
|
|
517
|
-
unless
|
|
518
|
-
raise GeneratorError.new("
|
|
549
|
+
unless Generator.valid_encoding?(key)
|
|
550
|
+
raise GeneratorError.new("source sequence is illegal/malformed utf-8", key)
|
|
519
551
|
end
|
|
520
552
|
end
|
|
521
553
|
|
|
@@ -527,24 +559,26 @@ module JSON
|
|
|
527
559
|
end
|
|
528
560
|
|
|
529
561
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
|
530
|
-
if state.strict? && !(
|
|
562
|
+
if state.strict? && !Generator.native_type?(value)
|
|
531
563
|
if state.as_json
|
|
532
|
-
value = state.as_json.call(value)
|
|
533
|
-
unless
|
|
564
|
+
value = state.as_json.call(value, false)
|
|
565
|
+
unless Generator.native_type?(value)
|
|
534
566
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
535
567
|
end
|
|
536
568
|
result << value.to_json(state)
|
|
569
|
+
state.depth = depth
|
|
537
570
|
else
|
|
538
571
|
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
|
539
572
|
end
|
|
540
573
|
elsif value.respond_to?(:to_json)
|
|
541
574
|
result << value.to_json(state)
|
|
575
|
+
state.depth = depth
|
|
542
576
|
else
|
|
543
577
|
result << %{"#{String(value)}"}
|
|
544
578
|
end
|
|
545
579
|
first = false
|
|
546
580
|
}
|
|
547
|
-
depth
|
|
581
|
+
depth -= 1
|
|
548
582
|
unless first
|
|
549
583
|
result << state.object_nl
|
|
550
584
|
result << state.indent * depth if indent
|
|
@@ -561,8 +595,11 @@ module JSON
|
|
|
561
595
|
# produced JSON string output further.
|
|
562
596
|
def to_json(state = nil, *)
|
|
563
597
|
state = State.from_state(state)
|
|
598
|
+
depth = state.depth
|
|
564
599
|
state.check_max_nesting
|
|
565
600
|
json_transform(state)
|
|
601
|
+
ensure
|
|
602
|
+
state.depth = depth
|
|
566
603
|
end
|
|
567
604
|
|
|
568
605
|
private
|
|
@@ -588,10 +625,10 @@ module JSON
|
|
|
588
625
|
each { |value|
|
|
589
626
|
result << delim unless first
|
|
590
627
|
result << state.indent * depth if indent
|
|
591
|
-
if state.strict? && !(
|
|
628
|
+
if state.strict? && !Generator.native_type?(value)
|
|
592
629
|
if state.as_json
|
|
593
|
-
value = state.as_json.call(value)
|
|
594
|
-
unless
|
|
630
|
+
value = state.as_json.call(value, false)
|
|
631
|
+
unless Generator.native_type?(value)
|
|
595
632
|
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
|
596
633
|
end
|
|
597
634
|
result << value.to_json(state)
|
|
@@ -600,12 +637,13 @@ module JSON
|
|
|
600
637
|
end
|
|
601
638
|
elsif value.respond_to?(:to_json)
|
|
602
639
|
result << value.to_json(state)
|
|
640
|
+
state.depth = depth
|
|
603
641
|
else
|
|
604
642
|
result << %{"#{String(value)}"}
|
|
605
643
|
end
|
|
606
644
|
first = false
|
|
607
645
|
}
|
|
608
|
-
depth
|
|
646
|
+
depth -= 1
|
|
609
647
|
result << state.array_nl
|
|
610
648
|
result << state.indent * depth if indent
|
|
611
649
|
result << ']'
|
|
@@ -625,11 +663,14 @@ module JSON
|
|
|
625
663
|
if state.allow_nan?
|
|
626
664
|
to_s
|
|
627
665
|
elsif state.strict? && state.as_json
|
|
628
|
-
casted_value = state.as_json.call(self)
|
|
666
|
+
casted_value = state.as_json.call(self, false)
|
|
629
667
|
|
|
630
668
|
if casted_value.equal?(self)
|
|
631
669
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
|
632
670
|
end
|
|
671
|
+
unless Generator.native_type?(casted_value)
|
|
672
|
+
raise GeneratorError.new("#{casted_value.class} returned by #{state.as_json} not allowed in JSON", casted_value)
|
|
673
|
+
end
|
|
633
674
|
|
|
634
675
|
state.check_max_nesting
|
|
635
676
|
state.depth += 1
|
|
@@ -662,14 +703,25 @@ module JSON
|
|
|
662
703
|
# \u????.
|
|
663
704
|
def to_json(state = nil, *args)
|
|
664
705
|
state = State.from_state(state)
|
|
665
|
-
|
|
666
|
-
|
|
706
|
+
string = self
|
|
707
|
+
|
|
708
|
+
if state.strict? && state.as_json
|
|
709
|
+
unless Generator.valid_encoding?(string)
|
|
710
|
+
string = state.as_json.call(string, false)
|
|
711
|
+
unless string.is_a?(::String)
|
|
712
|
+
return string.to_json(state, *args)
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
if string.encoding == ::Encoding::UTF_8
|
|
718
|
+
unless string.valid_encoding?
|
|
667
719
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
|
|
668
720
|
end
|
|
669
|
-
string = self
|
|
670
721
|
else
|
|
671
|
-
string = encode(::Encoding::UTF_8)
|
|
722
|
+
string = string.encode(::Encoding::UTF_8)
|
|
672
723
|
end
|
|
724
|
+
|
|
673
725
|
if state.ascii_only?
|
|
674
726
|
%("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}")
|
|
675
727
|
else
|
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+.
|
|
@@ -173,6 +182,30 @@ require 'json/common'
|
|
|
173
182
|
# When enabled:
|
|
174
183
|
# JSON.parse('[1,]', allow_trailing_comma: true) # => [1]
|
|
175
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
|
+
#
|
|
176
209
|
# ====== Output Options
|
|
177
210
|
#
|
|
178
211
|
# Option +freeze+ (boolean) specifies whether the returned objects will be frozen;
|
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.19.3
|
|
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
|
|
@@ -82,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
84
|
- !ruby/object:Gem::Version
|
|
83
85
|
version: '0'
|
|
84
86
|
requirements: []
|
|
85
|
-
rubygems_version:
|
|
87
|
+
rubygems_version: 4.0.3
|
|
86
88
|
specification_version: 4
|
|
87
89
|
summary: JSON Implementation for Ruby
|
|
88
90
|
test_files: []
|