json 2.6.2 → 2.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +46 -0
- data/README.md +4 -13
- data/ext/json/ext/generator/generator.c +122 -27
- data/ext/json/ext/generator/generator.h +8 -5
- data/ext/json/ext/parser/parser.c +1828 -2964
- data/ext/json/ext/parser/parser.rl +85 -100
- data/json.gemspec +7 -6
- data/lib/json/add/bigdecimal.rb +37 -8
- data/lib/json/add/complex.rb +28 -5
- data/lib/json/add/date.rb +26 -6
- data/lib/json/add/date_time.rb +25 -8
- data/lib/json/add/exception.rb +24 -6
- data/lib/json/add/ostruct.rb +31 -8
- data/lib/json/add/range.rb +32 -7
- data/lib/json/add/rational.rb +27 -5
- data/lib/json/add/regexp.rb +25 -7
- data/lib/json/add/set.rb +25 -6
- data/lib/json/add/struct.rb +28 -6
- data/lib/json/add/symbol.rb +27 -4
- data/lib/json/add/time.rb +26 -5
- data/lib/json/common.rb +29 -34
- data/lib/json/generic_object.rb +6 -2
- data/lib/json/pure/generator.rb +62 -28
- data/lib/json/pure/parser.rb +1 -1
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +9 -0
- metadata +6 -10
- data/VERSION +0 -1
data/lib/json/pure/generator.rb
CHANGED
@@ -37,25 +37,34 @@ module JSON
|
|
37
37
|
'\\' => '\\\\',
|
38
38
|
} # :nodoc:
|
39
39
|
|
40
|
-
|
40
|
+
ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
|
41
|
+
|
42
|
+
SCRIPT_SAFE_MAP = MAP.merge(
|
41
43
|
'/' => '\\/',
|
44
|
+
"\u2028".b => '\u2028',
|
45
|
+
"\u2029".b => '\u2029',
|
42
46
|
)
|
43
47
|
|
48
|
+
SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, "\u2029".b)
|
49
|
+
|
44
50
|
# Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
|
45
51
|
# UTF16 big endian characters as \u????, and return it.
|
46
|
-
def utf8_to_json(string,
|
52
|
+
def utf8_to_json(string, script_safe = false) # :nodoc:
|
47
53
|
string = string.dup
|
48
54
|
string.force_encoding(::Encoding::ASCII_8BIT)
|
49
|
-
|
50
|
-
|
55
|
+
if script_safe
|
56
|
+
string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
|
57
|
+
else
|
58
|
+
string.gsub!(ESCAPE_PATTERN) { MAP[$&] || $& }
|
59
|
+
end
|
51
60
|
string.force_encoding(::Encoding::UTF_8)
|
52
61
|
string
|
53
62
|
end
|
54
63
|
|
55
|
-
def utf8_to_json_ascii(string,
|
64
|
+
def utf8_to_json_ascii(string, script_safe = false) # :nodoc:
|
56
65
|
string = string.dup
|
57
66
|
string.force_encoding(::Encoding::ASCII_8BIT)
|
58
|
-
map =
|
67
|
+
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
59
68
|
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
60
69
|
string.gsub!(/(
|
61
70
|
(?:
|
@@ -115,7 +124,8 @@ module JSON
|
|
115
124
|
# * *space_before*: a string that is put before a : pair delimiter (default: ''),
|
116
125
|
# * *object_nl*: a string that is put at the end of a JSON object (default: ''),
|
117
126
|
# * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
118
|
-
# * *
|
127
|
+
# * *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped
|
128
|
+
# as to make the JSON object safe to interpolate in a script tag (default: false).
|
119
129
|
# * *check_circular*: is deprecated now, use the :max_nesting option instead,
|
120
130
|
# * *max_nesting*: sets the maximum level of data structure nesting in
|
121
131
|
# the generated JSON, max_nesting = 0 if no maximum should be checked.
|
@@ -130,7 +140,8 @@ module JSON
|
|
130
140
|
@array_nl = ''
|
131
141
|
@allow_nan = false
|
132
142
|
@ascii_only = false
|
133
|
-
@
|
143
|
+
@script_safe = false
|
144
|
+
@strict = false
|
134
145
|
@buffer_initial_length = 1024
|
135
146
|
configure opts
|
136
147
|
end
|
@@ -158,7 +169,11 @@ module JSON
|
|
158
169
|
|
159
170
|
# If this attribute is set to true, forward slashes will be escaped in
|
160
171
|
# all json strings.
|
161
|
-
attr_accessor :
|
172
|
+
attr_accessor :script_safe
|
173
|
+
|
174
|
+
# If this attribute is set to true, attempting to serialize types not
|
175
|
+
# supported by the JSON spec will raise a JSON::GeneratorError
|
176
|
+
attr_accessor :strict
|
162
177
|
|
163
178
|
# :stopdoc:
|
164
179
|
attr_reader :buffer_initial_length
|
@@ -200,8 +215,13 @@ module JSON
|
|
200
215
|
end
|
201
216
|
|
202
217
|
# Returns true, if forward slashes are escaped. Otherwise returns false.
|
203
|
-
def
|
204
|
-
@
|
218
|
+
def script_safe?
|
219
|
+
@script_safe
|
220
|
+
end
|
221
|
+
|
222
|
+
# Returns true, if forward slashes are escaped. Otherwise returns false.
|
223
|
+
def strict?
|
224
|
+
@strict
|
205
225
|
end
|
206
226
|
|
207
227
|
# Configure this State instance with the Hash _opts_, and return
|
@@ -214,7 +234,7 @@ module JSON
|
|
214
234
|
else
|
215
235
|
raise TypeError, "can't convert #{opts.class} into Hash"
|
216
236
|
end
|
217
|
-
|
237
|
+
opts.each do |key, value|
|
218
238
|
instance_variable_set "@#{key}", value
|
219
239
|
end
|
220
240
|
@indent = opts[:indent] if opts.key?(:indent)
|
@@ -226,7 +246,16 @@ module JSON
|
|
226
246
|
@ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
|
227
247
|
@depth = opts[:depth] || 0
|
228
248
|
@buffer_initial_length ||= opts[:buffer_initial_length]
|
229
|
-
|
249
|
+
|
250
|
+
@script_safe = if opts.key?(:script_safe)
|
251
|
+
!!opts[:script_safe]
|
252
|
+
elsif opts.key?(:escape_slash)
|
253
|
+
!!opts[:escape_slash]
|
254
|
+
else
|
255
|
+
false
|
256
|
+
end
|
257
|
+
|
258
|
+
@strict = !!opts[:strict] if opts.key?(:strict)
|
230
259
|
|
231
260
|
if !opts.key?(:max_nesting) # defaults to 100
|
232
261
|
@max_nesting = 100
|
@@ -243,7 +272,7 @@ module JSON
|
|
243
272
|
# passed to the configure method.
|
244
273
|
def to_h
|
245
274
|
result = {}
|
246
|
-
|
275
|
+
instance_variables.each do |iv|
|
247
276
|
iv = iv.to_s[1..-1]
|
248
277
|
result[iv.to_sym] = self[iv]
|
249
278
|
end
|
@@ -287,7 +316,13 @@ module JSON
|
|
287
316
|
# Converts this object to a string (calling #to_s), converts
|
288
317
|
# it to a JSON string, and returns the result. This is a fallback, if no
|
289
318
|
# special method #to_json was defined for some object.
|
290
|
-
def to_json(
|
319
|
+
def to_json(generator_state)
|
320
|
+
if generator_state.strict?
|
321
|
+
raise GeneratorError, "#{self.class} not allowed in JSON"
|
322
|
+
else
|
323
|
+
to_s.to_json
|
324
|
+
end
|
325
|
+
end
|
291
326
|
end
|
292
327
|
|
293
328
|
module Hash
|
@@ -310,21 +345,18 @@ module JSON
|
|
310
345
|
end
|
311
346
|
|
312
347
|
def json_transform(state)
|
313
|
-
delim =
|
314
|
-
|
315
|
-
result = '{'
|
316
|
-
result << state.object_nl
|
348
|
+
delim = ",#{state.object_nl}"
|
349
|
+
result = "{#{state.object_nl}"
|
317
350
|
depth = state.depth += 1
|
318
351
|
first = true
|
319
352
|
indent = !state.object_nl.empty?
|
320
|
-
each { |key,value|
|
353
|
+
each { |key, value|
|
321
354
|
result << delim unless first
|
322
355
|
result << state.indent * depth if indent
|
323
|
-
result
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
if value.respond_to?(:to_json)
|
356
|
+
result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}"
|
357
|
+
if state.strict?
|
358
|
+
raise GeneratorError, "#{value.class} not allowed in JSON"
|
359
|
+
elsif value.respond_to?(:to_json)
|
328
360
|
result << value.to_json(state)
|
329
361
|
else
|
330
362
|
result << %{"#{String(value)}"}
|
@@ -365,7 +397,9 @@ module JSON
|
|
365
397
|
each { |value|
|
366
398
|
result << delim unless first
|
367
399
|
result << state.indent * depth if indent
|
368
|
-
if
|
400
|
+
if state.strict?
|
401
|
+
raise GeneratorError, "#{value.class} not allowed in JSON"
|
402
|
+
elsif value.respond_to?(:to_json)
|
369
403
|
result << value.to_json(state)
|
370
404
|
else
|
371
405
|
result << %{"#{String(value)}"}
|
@@ -419,9 +453,9 @@ module JSON
|
|
419
453
|
string = encode(::Encoding::UTF_8)
|
420
454
|
end
|
421
455
|
if state.ascii_only?
|
422
|
-
'"' << JSON.utf8_to_json_ascii(string, state.
|
456
|
+
'"' << JSON.utf8_to_json_ascii(string, state.script_safe) << '"'
|
423
457
|
else
|
424
|
-
'"' << JSON.utf8_to_json(string, state.
|
458
|
+
'"' << JSON.utf8_to_json(string, state.script_safe) << '"'
|
425
459
|
end
|
426
460
|
end
|
427
461
|
|
data/lib/json/pure/parser.rb
CHANGED
@@ -179,7 +179,7 @@ module JSON
|
|
179
179
|
bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
|
180
180
|
i += 1
|
181
181
|
end
|
182
|
-
JSON.iconv('utf-8', 'utf-16be', bytes)
|
182
|
+
JSON.iconv('utf-8', 'utf-16be', bytes).force_encoding(::Encoding::ASCII_8BIT)
|
183
183
|
end
|
184
184
|
end
|
185
185
|
if string.respond_to?(:force_encoding)
|
data/lib/json/version.rb
CHANGED
data/lib/json.rb
CHANGED
@@ -285,6 +285,15 @@ require 'json/common'
|
|
285
285
|
# # Raises JSON::NestingError (nesting of 2 is too deep):
|
286
286
|
# JSON.generate(obj, max_nesting: 2)
|
287
287
|
#
|
288
|
+
# ====== Escaping Options
|
289
|
+
#
|
290
|
+
# Options +script_safe+ (boolean) specifies wether <tt>'\u2028'</tt>, <tt>'\u2029'</tt>
|
291
|
+
# and <tt>'/'</tt> should be escaped as to make the JSON object safe to interpolate in script
|
292
|
+
# tags.
|
293
|
+
#
|
294
|
+
# Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range
|
295
|
+
# should be escaped.
|
296
|
+
#
|
288
297
|
# ====== Output Options
|
289
298
|
#
|
290
299
|
# The default formatting options generate the most compact
|
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.7.2
|
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: 2024-04-04 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
|
@@ -23,7 +22,6 @@ files:
|
|
23
22
|
- CHANGES.md
|
24
23
|
- LICENSE
|
25
24
|
- README.md
|
26
|
-
- VERSION
|
27
25
|
- ext/json/ext/fbuffer/fbuffer.h
|
28
26
|
- ext/json/ext/generator/depend
|
29
27
|
- ext/json/ext/generator/extconf.rb
|
@@ -58,17 +56,16 @@ files:
|
|
58
56
|
- lib/json/pure/generator.rb
|
59
57
|
- lib/json/pure/parser.rb
|
60
58
|
- lib/json/version.rb
|
61
|
-
homepage:
|
59
|
+
homepage: https://flori.github.io/json
|
62
60
|
licenses:
|
63
61
|
- Ruby
|
64
62
|
metadata:
|
65
63
|
bug_tracker_uri: https://github.com/flori/json/issues
|
66
64
|
changelog_uri: https://github.com/flori/json/blob/master/CHANGES.md
|
67
|
-
documentation_uri:
|
68
|
-
homepage_uri:
|
65
|
+
documentation_uri: https://flori.github.io/json/doc/index.html
|
66
|
+
homepage_uri: https://flori.github.io/json
|
69
67
|
source_code_uri: https://github.com/flori/json
|
70
68
|
wiki_uri: https://github.com/flori/json/wiki
|
71
|
-
post_install_message:
|
72
69
|
rdoc_options:
|
73
70
|
- "--title"
|
74
71
|
- JSON implementation for Ruby
|
@@ -87,8 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
84
|
- !ruby/object:Gem::Version
|
88
85
|
version: '0'
|
89
86
|
requirements: []
|
90
|
-
rubygems_version: 3.
|
91
|
-
signing_key:
|
87
|
+
rubygems_version: 3.6.0.dev
|
92
88
|
specification_version: 4
|
93
89
|
summary: JSON Implementation for Ruby
|
94
90
|
test_files: []
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.6.2
|