json 2.9.1 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +7 -0
- data/LEGAL +0 -52
- data/README.md +75 -2
- data/ext/json/ext/fbuffer/fbuffer.h +1 -10
- data/ext/json/ext/generator/generator.c +394 -263
- data/ext/json/ext/parser/parser.c +762 -2522
- data/json.gemspec +3 -4
- data/lib/json/add/symbol.rb +7 -2
- data/lib/json/common.rb +107 -10
- data/lib/json/ext/generator/state.rb +1 -11
- data/lib/json/ext.rb +26 -4
- data/lib/json/truffle_ruby/generator.rb +111 -50
- data/lib/json/version.rb +1 -1
- metadata +6 -11
- data/ext/json/ext/parser/parser.rl +0 -1465
data/json.gemspec
CHANGED
@@ -11,14 +11,13 @@ spec = Gem::Specification.new do |s|
|
|
11
11
|
s.version = version
|
12
12
|
|
13
13
|
s.summary = "JSON Implementation for Ruby"
|
14
|
-
s.homepage = "https://
|
14
|
+
s.homepage = "https://github.com/ruby/json"
|
15
15
|
s.metadata = {
|
16
16
|
'bug_tracker_uri' => 'https://github.com/ruby/json/issues',
|
17
17
|
'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md',
|
18
|
-
'documentation_uri' => 'https://ruby.
|
18
|
+
'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html',
|
19
19
|
'homepage_uri' => s.homepage,
|
20
20
|
'source_code_uri' => 'https://github.com/ruby/json',
|
21
|
-
'wiki_uri' => 'https://github.com/ruby/json/wiki'
|
22
21
|
}
|
23
22
|
|
24
23
|
s.required_ruby_version = Gem::Requirement.new(">= 2.7")
|
@@ -53,7 +52,7 @@ spec = Gem::Specification.new do |s|
|
|
53
52
|
s.files += Dir["lib/json/ext/**/*.jar"]
|
54
53
|
else
|
55
54
|
s.extensions = Dir["ext/json/**/extconf.rb"]
|
56
|
-
s.files += Dir["ext/json/**/*.{c,h
|
55
|
+
s.files += Dir["ext/json/**/*.{c,h}"]
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
data/lib/json/add/symbol.rb
CHANGED
@@ -36,8 +36,13 @@ class Symbol
|
|
36
36
|
#
|
37
37
|
# # {"json_class":"Symbol","s":"foo"}
|
38
38
|
#
|
39
|
-
def to_json(*a)
|
40
|
-
|
39
|
+
def to_json(state = nil, *a)
|
40
|
+
state = ::JSON::State.from_state(state)
|
41
|
+
if state.strict?
|
42
|
+
super
|
43
|
+
else
|
44
|
+
as_json.to_json(state, *a)
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
48
|
# See #as_json.
|
data/lib/json/common.rb
CHANGED
@@ -167,6 +167,30 @@ module JSON
|
|
167
167
|
# system. Usually this means that the iconv library is not installed.
|
168
168
|
class MissingUnicodeSupport < JSONError; end
|
169
169
|
|
170
|
+
# Fragment of JSON document that is to be included as is:
|
171
|
+
# fragment = JSON::Fragment.new("[1, 2, 3]")
|
172
|
+
# JSON.generate({ count: 3, items: fragments })
|
173
|
+
#
|
174
|
+
# This allows to easily assemble multiple JSON fragments that have
|
175
|
+
# been persisted somewhere without having to parse them nor resorting
|
176
|
+
# to string interpolation.
|
177
|
+
#
|
178
|
+
# Note: no validation is performed on the provided string. It is the
|
179
|
+
# responsability of the caller to ensure the string contains valid JSON.
|
180
|
+
Fragment = Struct.new(:json) do
|
181
|
+
def initialize(json)
|
182
|
+
unless string = String.try_convert(json)
|
183
|
+
raise TypeError, " no implicit conversion of #{json.class} into String"
|
184
|
+
end
|
185
|
+
|
186
|
+
super(string)
|
187
|
+
end
|
188
|
+
|
189
|
+
def to_json(state = nil, *)
|
190
|
+
json
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
170
194
|
module_function
|
171
195
|
|
172
196
|
# :call-seq:
|
@@ -232,12 +256,13 @@ module JSON
|
|
232
256
|
# - Option +max_nesting+, if not provided, defaults to +false+,
|
233
257
|
# which disables checking for nesting depth.
|
234
258
|
# - Option +allow_nan+, if not provided, defaults to +true+.
|
235
|
-
def parse!(source, opts =
|
236
|
-
|
259
|
+
def parse!(source, opts = nil)
|
260
|
+
options = {
|
237
261
|
:max_nesting => false,
|
238
262
|
:allow_nan => true
|
239
|
-
}
|
240
|
-
|
263
|
+
}
|
264
|
+
options.merge!(opts) if opts
|
265
|
+
Parser.new(source, options).parse
|
241
266
|
end
|
242
267
|
|
243
268
|
# :call-seq:
|
@@ -258,7 +283,7 @@ module JSON
|
|
258
283
|
# JSON.parse!(File.read(path, opts))
|
259
284
|
#
|
260
285
|
# See method #parse!
|
261
|
-
def load_file!(filespec, opts =
|
286
|
+
def load_file!(filespec, opts = nil)
|
262
287
|
parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
|
263
288
|
end
|
264
289
|
|
@@ -818,11 +843,7 @@ module JSON
|
|
818
843
|
opts = merge_dump_options(opts, **kwargs) if kwargs
|
819
844
|
|
820
845
|
begin
|
821
|
-
|
822
|
-
opts.generate(obj, anIO)
|
823
|
-
else
|
824
|
-
State.generate(obj, opts, anIO)
|
825
|
-
end
|
846
|
+
State.generate(obj, opts, anIO)
|
826
847
|
rescue JSON::NestingError
|
827
848
|
raise ArgumentError, "exceed depth limit"
|
828
849
|
end
|
@@ -841,6 +862,82 @@ module JSON
|
|
841
862
|
class << self
|
842
863
|
private :merge_dump_options
|
843
864
|
end
|
865
|
+
|
866
|
+
# JSON::Coder holds a parser and generator configuration.
|
867
|
+
#
|
868
|
+
# module MyApp
|
869
|
+
# JSONC_CODER = JSON::Coder.new(
|
870
|
+
# allow_trailing_comma: true
|
871
|
+
# )
|
872
|
+
# end
|
873
|
+
#
|
874
|
+
# MyApp::JSONC_CODER.load(document)
|
875
|
+
#
|
876
|
+
class Coder
|
877
|
+
# :call-seq:
|
878
|
+
# JSON.new(options = nil, &block)
|
879
|
+
#
|
880
|
+
# Argument +options+, if given, contains a \Hash of options for both parsing and generating.
|
881
|
+
# See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
|
882
|
+
#
|
883
|
+
# For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
|
884
|
+
# encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
|
885
|
+
# \JSON counterpart:
|
886
|
+
#
|
887
|
+
# module MyApp
|
888
|
+
# API_JSON_CODER = JSON::Coder.new do |object|
|
889
|
+
# case object
|
890
|
+
# when Time
|
891
|
+
# object.iso8601(3)
|
892
|
+
# else
|
893
|
+
# object # Unknown type, will raise
|
894
|
+
# end
|
895
|
+
# end
|
896
|
+
# end
|
897
|
+
#
|
898
|
+
# puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
|
899
|
+
#
|
900
|
+
def initialize(options = nil, &as_json)
|
901
|
+
if options.nil?
|
902
|
+
options = { strict: true }
|
903
|
+
else
|
904
|
+
options = options.dup
|
905
|
+
options[:strict] = true
|
906
|
+
end
|
907
|
+
options[:as_json] = as_json if as_json
|
908
|
+
options[:create_additions] = false unless options.key?(:create_additions)
|
909
|
+
|
910
|
+
@state = State.new(options).freeze
|
911
|
+
@parser_config = Ext::Parser::Config.new(options)
|
912
|
+
end
|
913
|
+
|
914
|
+
# call-seq:
|
915
|
+
# dump(object) -> String
|
916
|
+
# dump(object, io) -> io
|
917
|
+
#
|
918
|
+
# Serialize the given object into a \JSON document.
|
919
|
+
def dump(object, io = nil)
|
920
|
+
@state.generate_new(object, io)
|
921
|
+
end
|
922
|
+
alias_method :generate, :dump
|
923
|
+
|
924
|
+
# call-seq:
|
925
|
+
# load(string) -> Object
|
926
|
+
#
|
927
|
+
# Parse the given \JSON document and return an equivalent Ruby object.
|
928
|
+
def load(source)
|
929
|
+
@parser_config.parse(source)
|
930
|
+
end
|
931
|
+
alias_method :parse, :load
|
932
|
+
|
933
|
+
# call-seq:
|
934
|
+
# load(path) -> Object
|
935
|
+
#
|
936
|
+
# Parse the given \JSON document and return an equivalent Ruby object.
|
937
|
+
def load_file(path)
|
938
|
+
load(File.read(path, encoding: Encoding::UTF_8))
|
939
|
+
end
|
940
|
+
end
|
844
941
|
end
|
845
942
|
|
846
943
|
module ::Kernel
|
@@ -47,17 +47,6 @@ module JSON
|
|
47
47
|
|
48
48
|
alias_method :merge, :configure
|
49
49
|
|
50
|
-
# call-seq:
|
51
|
-
# generate(obj) -> String
|
52
|
-
# generate(obj, anIO) -> anIO
|
53
|
-
#
|
54
|
-
# Generates a valid JSON document from object +obj+ and returns the
|
55
|
-
# result. If no valid JSON document can be created this method raises a
|
56
|
-
# GeneratorError exception.
|
57
|
-
def generate(obj, io = nil)
|
58
|
-
_generate(obj, io)
|
59
|
-
end
|
60
|
-
|
61
50
|
# call-seq: to_h
|
62
51
|
#
|
63
52
|
# Returns the configuration instance variables as a hash, that can be
|
@@ -69,6 +58,7 @@ module JSON
|
|
69
58
|
space_before: space_before,
|
70
59
|
object_nl: object_nl,
|
71
60
|
array_nl: array_nl,
|
61
|
+
as_json: as_json,
|
72
62
|
allow_nan: allow_nan?,
|
73
63
|
ascii_only: ascii_only?,
|
74
64
|
max_nesting: max_nesting,
|
data/lib/json/ext.rb
CHANGED
@@ -6,15 +6,37 @@ module JSON
|
|
6
6
|
# This module holds all the modules/classes that implement JSON's
|
7
7
|
# functionality as C extensions.
|
8
8
|
module Ext
|
9
|
+
class Parser
|
10
|
+
class << self
|
11
|
+
def parse(...)
|
12
|
+
new(...).parse
|
13
|
+
end
|
14
|
+
alias_method :parse, :parse # Allow redefinition by extensions
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(source, opts = nil)
|
18
|
+
@source = source
|
19
|
+
@config = Config.new(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def source
|
23
|
+
@source.dup
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse
|
27
|
+
@config.parse(@source)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'json/ext/parser'
|
32
|
+
Ext::Parser::Config = Ext::ParserConfig
|
33
|
+
JSON.parser = Ext::Parser
|
34
|
+
|
9
35
|
if RUBY_ENGINE == 'truffleruby'
|
10
|
-
require 'json/ext/parser'
|
11
36
|
require 'json/truffle_ruby/generator'
|
12
|
-
JSON.parser = Parser
|
13
37
|
JSON.generator = ::JSON::TruffleRuby::Generator
|
14
38
|
else
|
15
|
-
require 'json/ext/parser'
|
16
39
|
require 'json/ext/generator'
|
17
|
-
JSON.parser = Parser
|
18
40
|
JSON.generator = Generator
|
19
41
|
end
|
20
42
|
end
|
@@ -39,30 +39,33 @@ module JSON
|
|
39
39
|
'\\' => '\\\\',
|
40
40
|
}.freeze # :nodoc:
|
41
41
|
|
42
|
-
ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
|
43
|
-
|
44
42
|
SCRIPT_SAFE_MAP = MAP.merge(
|
45
43
|
'/' => '\\/',
|
46
|
-
"\u2028"
|
47
|
-
"\u2029"
|
44
|
+
"\u2028" => '\u2028',
|
45
|
+
"\u2029" => '\u2029',
|
48
46
|
).freeze
|
49
47
|
|
50
|
-
SCRIPT_SAFE_ESCAPE_PATTERN =
|
48
|
+
SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
|
51
49
|
|
52
50
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
53
51
|
# UTF16 big endian characters as \u????, and return it.
|
54
|
-
def utf8_to_json(string, script_safe = false) # :nodoc:
|
55
|
-
string = string.b
|
52
|
+
def self.utf8_to_json(string, script_safe = false) # :nodoc:
|
56
53
|
if script_safe
|
57
|
-
|
54
|
+
if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string)
|
55
|
+
string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP)
|
56
|
+
else
|
57
|
+
string
|
58
|
+
end
|
58
59
|
else
|
59
|
-
|
60
|
+
if /["\\\x0-\x1f]/.match?(string)
|
61
|
+
string.gsub(/["\\\x0-\x1f]/, MAP)
|
62
|
+
else
|
63
|
+
string
|
64
|
+
end
|
60
65
|
end
|
61
|
-
string.force_encoding(::Encoding::UTF_8)
|
62
|
-
string
|
63
66
|
end
|
64
67
|
|
65
|
-
def utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
|
68
|
+
def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
|
66
69
|
string = original_string.b
|
67
70
|
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
68
71
|
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
@@ -86,24 +89,17 @@ module JSON
|
|
86
89
|
raise GeneratorError.new(e.message, original_string)
|
87
90
|
end
|
88
91
|
|
89
|
-
def valid_utf8?(string)
|
92
|
+
def self.valid_utf8?(string)
|
90
93
|
encoding = string.encoding
|
91
94
|
(encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
|
92
95
|
string.valid_encoding?
|
93
96
|
end
|
94
|
-
module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
|
95
97
|
|
96
98
|
# This class is used to create State instances, that are use to hold data
|
97
99
|
# while generating a JSON text from a Ruby data structure.
|
98
100
|
class State
|
99
101
|
def self.generate(obj, opts = nil, io = nil)
|
100
|
-
|
101
|
-
if io
|
102
|
-
io.write(string)
|
103
|
-
io
|
104
|
-
else
|
105
|
-
string
|
106
|
-
end
|
102
|
+
new(opts).generate(obj, io)
|
107
103
|
end
|
108
104
|
|
109
105
|
# Creates a State object from _opts_, which ought to be Hash to create
|
@@ -111,16 +107,17 @@ module JSON
|
|
111
107
|
# an unconfigured instance. If _opts_ is a State object, it is just
|
112
108
|
# returned.
|
113
109
|
def self.from_state(opts)
|
114
|
-
|
115
|
-
|
116
|
-
opts
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
110
|
+
if opts
|
111
|
+
case
|
112
|
+
when self === opts
|
113
|
+
return opts
|
114
|
+
when opts.respond_to?(:to_hash)
|
115
|
+
return new(opts.to_hash)
|
116
|
+
when opts.respond_to?(:to_h)
|
117
|
+
return new(opts.to_h)
|
118
|
+
end
|
123
119
|
end
|
120
|
+
SAFE_STATE_PROTOTYPE.dup
|
124
121
|
end
|
125
122
|
|
126
123
|
# Instantiates a new State object, configured by _opts_.
|
@@ -148,6 +145,7 @@ module JSON
|
|
148
145
|
@array_nl = ''
|
149
146
|
@allow_nan = false
|
150
147
|
@ascii_only = false
|
148
|
+
@as_json = false
|
151
149
|
@depth = 0
|
152
150
|
@buffer_initial_length = 1024
|
153
151
|
@script_safe = false
|
@@ -173,6 +171,9 @@ module JSON
|
|
173
171
|
# This string is put at the end of a line that holds a JSON array.
|
174
172
|
attr_accessor :array_nl
|
175
173
|
|
174
|
+
# This proc converts unsupported types into native JSON types.
|
175
|
+
attr_accessor :as_json
|
176
|
+
|
176
177
|
# This integer returns the maximum level of data structure nesting in
|
177
178
|
# the generated JSON, max_nesting = 0 if no maximum is checked.
|
178
179
|
attr_accessor :max_nesting
|
@@ -257,6 +258,7 @@ module JSON
|
|
257
258
|
@object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
|
258
259
|
@array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
|
259
260
|
@allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
|
261
|
+
@as_json = opts[:as_json].to_proc if opts.key?(:as_json)
|
260
262
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
261
263
|
@depth = opts[:depth] || 0
|
262
264
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
@@ -299,9 +301,9 @@ module JSON
|
|
299
301
|
# returns the result. If no valid JSON document can be
|
300
302
|
# created this method raises a
|
301
303
|
# GeneratorError exception.
|
302
|
-
def generate(obj)
|
304
|
+
def generate(obj, anIO = nil)
|
303
305
|
if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
|
304
|
-
!@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
|
306
|
+
!@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
|
305
307
|
result = generate_json(obj, ''.dup)
|
306
308
|
else
|
307
309
|
result = obj.to_json(self)
|
@@ -310,7 +312,16 @@ module JSON
|
|
310
312
|
"source sequence #{result.inspect} is illegal/malformed utf-8",
|
311
313
|
obj
|
312
314
|
)
|
313
|
-
|
315
|
+
if anIO
|
316
|
+
anIO.write(result)
|
317
|
+
anIO
|
318
|
+
else
|
319
|
+
result
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def generate_new(obj, anIO = nil) # :nodoc:
|
324
|
+
dup.generate(obj, anIO)
|
314
325
|
end
|
315
326
|
|
316
327
|
# Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
|
@@ -353,6 +364,12 @@ module JSON
|
|
353
364
|
end
|
354
365
|
when Integer
|
355
366
|
buf << obj.to_s
|
367
|
+
when Symbol
|
368
|
+
if @strict
|
369
|
+
fast_serialize_string(obj.name, buf)
|
370
|
+
else
|
371
|
+
buf << obj.to_json(self)
|
372
|
+
end
|
356
373
|
else
|
357
374
|
# Note: Float is handled this way since Float#to_s is slow anyway
|
358
375
|
buf << obj.to_json(self)
|
@@ -371,8 +388,8 @@ module JSON
|
|
371
388
|
end
|
372
389
|
raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
|
373
390
|
|
374
|
-
if /["\\\x0-\x1f]
|
375
|
-
buf << string.gsub(/["\\\x0-\x1f]
|
391
|
+
if /["\\\x0-\x1f]/.match?(string)
|
392
|
+
buf << string.gsub(/["\\\x0-\x1f]/, MAP)
|
376
393
|
else
|
377
394
|
buf << string
|
378
395
|
end
|
@@ -404,8 +421,20 @@ module JSON
|
|
404
421
|
# it to a JSON string, and returns the result. This is a fallback, if no
|
405
422
|
# special method #to_json was defined for some object.
|
406
423
|
def to_json(state = nil, *)
|
407
|
-
|
408
|
-
|
424
|
+
state = State.from_state(state) if state
|
425
|
+
if state&.strict?
|
426
|
+
value = self
|
427
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
428
|
+
if state.as_json
|
429
|
+
value = state.as_json.call(value)
|
430
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
|
431
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
432
|
+
end
|
433
|
+
value.to_json(state)
|
434
|
+
else
|
435
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
436
|
+
end
|
437
|
+
end
|
409
438
|
else
|
410
439
|
to_s.to_json
|
411
440
|
end
|
@@ -455,8 +484,16 @@ module JSON
|
|
455
484
|
end
|
456
485
|
|
457
486
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
458
|
-
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
459
|
-
|
487
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
|
488
|
+
if state.as_json
|
489
|
+
value = state.as_json.call(value)
|
490
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
|
491
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
492
|
+
end
|
493
|
+
result << value.to_json(state)
|
494
|
+
else
|
495
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
496
|
+
end
|
460
497
|
elsif value.respond_to?(:to_json)
|
461
498
|
result << value.to_json(state)
|
462
499
|
else
|
@@ -508,8 +545,16 @@ module JSON
|
|
508
545
|
each { |value|
|
509
546
|
result << delim unless first
|
510
547
|
result << state.indent * depth if indent
|
511
|
-
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
512
|
-
|
548
|
+
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value)
|
549
|
+
if state.as_json
|
550
|
+
value = state.as_json.call(value)
|
551
|
+
unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value
|
552
|
+
raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
|
553
|
+
end
|
554
|
+
result << value.to_json(state)
|
555
|
+
else
|
556
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
557
|
+
end
|
513
558
|
elsif value.respond_to?(:to_json)
|
514
559
|
result << value.to_json(state)
|
515
560
|
else
|
@@ -531,18 +576,23 @@ module JSON
|
|
531
576
|
|
532
577
|
module Float
|
533
578
|
# Returns a JSON string representation for this Float number.
|
534
|
-
def to_json(state = nil, *)
|
579
|
+
def to_json(state = nil, *args)
|
535
580
|
state = State.from_state(state)
|
536
|
-
|
537
|
-
when infinite?
|
538
|
-
if state.allow_nan?
|
539
|
-
to_s
|
540
|
-
else
|
541
|
-
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
542
|
-
end
|
543
|
-
when nan?
|
581
|
+
if infinite? || nan?
|
544
582
|
if state.allow_nan?
|
545
583
|
to_s
|
584
|
+
elsif state.strict? && state.as_json
|
585
|
+
casted_value = state.as_json.call(self)
|
586
|
+
|
587
|
+
if casted_value.equal?(self)
|
588
|
+
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
589
|
+
end
|
590
|
+
|
591
|
+
state.check_max_nesting
|
592
|
+
state.depth += 1
|
593
|
+
result = casted_value.to_json(state, *args)
|
594
|
+
state.depth -= 1
|
595
|
+
result
|
546
596
|
else
|
547
597
|
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
548
598
|
end
|
@@ -552,6 +602,17 @@ module JSON
|
|
552
602
|
end
|
553
603
|
end
|
554
604
|
|
605
|
+
module Symbol
|
606
|
+
def to_json(state = nil, *args)
|
607
|
+
state = State.from_state(state)
|
608
|
+
if state.strict?
|
609
|
+
name.to_json(state, *args)
|
610
|
+
else
|
611
|
+
super
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
555
616
|
module String
|
556
617
|
# This string should be encoded with UTF-8 A call to this method
|
557
618
|
# returns a JSON string encoded with UTF16 big endian characters as
|
data/lib/json/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +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.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-02-10 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: This is a JSON implementation as a Ruby extension in C.
|
14
13
|
email: flori@ping.de
|
@@ -29,7 +28,6 @@ files:
|
|
29
28
|
- ext/json/ext/generator/generator.c
|
30
29
|
- ext/json/ext/parser/extconf.rb
|
31
30
|
- ext/json/ext/parser/parser.c
|
32
|
-
- ext/json/ext/parser/parser.rl
|
33
31
|
- json.gemspec
|
34
32
|
- lib/json.rb
|
35
33
|
- lib/json/add/bigdecimal.rb
|
@@ -52,17 +50,15 @@ files:
|
|
52
50
|
- lib/json/generic_object.rb
|
53
51
|
- lib/json/truffle_ruby/generator.rb
|
54
52
|
- lib/json/version.rb
|
55
|
-
homepage: https://
|
53
|
+
homepage: https://github.com/ruby/json
|
56
54
|
licenses:
|
57
55
|
- Ruby
|
58
56
|
metadata:
|
59
57
|
bug_tracker_uri: https://github.com/ruby/json/issues
|
60
58
|
changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
|
61
|
-
documentation_uri: https://ruby.
|
62
|
-
homepage_uri: https://
|
59
|
+
documentation_uri: https://docs.ruby-lang.org/en/master/JSON.html
|
60
|
+
homepage_uri: https://github.com/ruby/json
|
63
61
|
source_code_uri: https://github.com/ruby/json
|
64
|
-
wiki_uri: https://github.com/ruby/json/wiki
|
65
|
-
post_install_message:
|
66
62
|
rdoc_options:
|
67
63
|
- "--title"
|
68
64
|
- JSON implementation for Ruby
|
@@ -81,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
77
|
- !ruby/object:Gem::Version
|
82
78
|
version: '0'
|
83
79
|
requirements: []
|
84
|
-
rubygems_version: 3.
|
85
|
-
signing_key:
|
80
|
+
rubygems_version: 3.6.2
|
86
81
|
specification_version: 4
|
87
82
|
summary: JSON Implementation for Ruby
|
88
83
|
test_files: []
|