json 2.8.2 → 2.9.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 +9 -0
- data/ext/json/ext/fbuffer/fbuffer.h +46 -16
- data/ext/json/ext/generator/generator.c +68 -40
- data/ext/json/ext/parser/extconf.rb +0 -1
- data/ext/json/ext/parser/parser.c +124 -132
- data/ext/json/ext/parser/parser.rl +8 -16
- data/lib/json/common.rb +38 -18
- data/lib/json/ext/generator/state.rb +11 -0
- data/lib/json/truffle_ruby/generator.rb +25 -17
- data/lib/json/version.rb +1 -1
- metadata +2 -2
@@ -26,19 +26,6 @@ static const char deprecated_create_additions_warning[] =
|
|
26
26
|
"and will be removed in 3.0, use JSON.unsafe_load or explicitly "
|
27
27
|
"pass `create_additions: true`";
|
28
28
|
|
29
|
-
#ifndef HAVE_RB_GC_MARK_LOCATIONS
|
30
|
-
// For TruffleRuby
|
31
|
-
void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
|
32
|
-
{
|
33
|
-
VALUE *value = start;
|
34
|
-
|
35
|
-
while (value < end) {
|
36
|
-
rb_gc_mark(*value);
|
37
|
-
value++;
|
38
|
-
}
|
39
|
-
}
|
40
|
-
#endif
|
41
|
-
|
42
29
|
#ifndef HAVE_RB_HASH_BULK_INSERT
|
43
30
|
// For TruffleRuby
|
44
31
|
void rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash)
|
@@ -264,7 +251,10 @@ static inline void rvalue_stack_pop(rvalue_stack *stack, long count)
|
|
264
251
|
static void rvalue_stack_mark(void *ptr)
|
265
252
|
{
|
266
253
|
rvalue_stack *stack = (rvalue_stack *)ptr;
|
267
|
-
|
254
|
+
long index;
|
255
|
+
for (index = 0; index < stack->head; index++) {
|
256
|
+
rb_gc_mark(stack->ptr[index]);
|
257
|
+
}
|
268
258
|
}
|
269
259
|
|
270
260
|
static void rvalue_stack_free(void *ptr)
|
@@ -1349,8 +1339,10 @@ static void JSON_mark(void *ptr)
|
|
1349
1339
|
rb_gc_mark(json->match_string);
|
1350
1340
|
rb_gc_mark(json->stack_handle);
|
1351
1341
|
|
1352
|
-
|
1353
|
-
|
1342
|
+
long index;
|
1343
|
+
for (index = 0; index < json->name_cache.length; index++) {
|
1344
|
+
rb_gc_mark(json->name_cache.entries[index]);
|
1345
|
+
}
|
1354
1346
|
}
|
1355
1347
|
|
1356
1348
|
static void JSON_free(void *ptr)
|
data/lib/json/common.rb
CHANGED
@@ -143,7 +143,23 @@ module JSON
|
|
143
143
|
# :startdoc:
|
144
144
|
|
145
145
|
# This exception is raised if a generator or unparser error occurs.
|
146
|
-
class GeneratorError < JSONError
|
146
|
+
class GeneratorError < JSONError
|
147
|
+
attr_reader :invalid_object
|
148
|
+
|
149
|
+
def initialize(message, invalid_object = nil)
|
150
|
+
super(message)
|
151
|
+
@invalid_object = invalid_object
|
152
|
+
end
|
153
|
+
|
154
|
+
def detailed_message(...)
|
155
|
+
if @invalid_object.nil?
|
156
|
+
super
|
157
|
+
else
|
158
|
+
"#{super}\nInvalid object: #{@invalid_object.inspect}"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
147
163
|
# For backwards compatibility
|
148
164
|
UnparserError = GeneratorError # :nodoc:
|
149
165
|
|
@@ -286,7 +302,7 @@ module JSON
|
|
286
302
|
if State === opts
|
287
303
|
opts.generate(obj)
|
288
304
|
else
|
289
|
-
State.generate(obj, opts)
|
305
|
+
State.generate(obj, opts, nil)
|
290
306
|
end
|
291
307
|
end
|
292
308
|
|
@@ -411,6 +427,10 @@ module JSON
|
|
411
427
|
#
|
412
428
|
# Returns the Ruby objects created by parsing the given +source+.
|
413
429
|
#
|
430
|
+
# BEWARE: This method is meant to serialise data from trusted user input,
|
431
|
+
# like from your own database server or clients under your control, it could
|
432
|
+
# be dangerous to allow untrusted users to pass JSON sources into it.
|
433
|
+
#
|
414
434
|
# - Argument +source+ must be, or be convertible to, a \String:
|
415
435
|
# - If +source+ responds to instance method +to_str+,
|
416
436
|
# <tt>source.to_str</tt> becomes the source.
|
@@ -425,9 +445,6 @@ module JSON
|
|
425
445
|
# - Argument +proc+, if given, must be a \Proc that accepts one argument.
|
426
446
|
# It will be called recursively with each result (depth-first order).
|
427
447
|
# See details below.
|
428
|
-
# BEWARE: This method is meant to serialise data from trusted user input,
|
429
|
-
# like from your own database server or clients under your control, it could
|
430
|
-
# be dangerous to allow untrusted users to pass JSON sources into it.
|
431
448
|
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
432
449
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
433
450
|
# The default options can be changed via method JSON.unsafe_load_default_options=.
|
@@ -564,6 +581,16 @@ module JSON
|
|
564
581
|
#
|
565
582
|
# Returns the Ruby objects created by parsing the given +source+.
|
566
583
|
#
|
584
|
+
# BEWARE: This method is meant to serialise data from trusted user input,
|
585
|
+
# like from your own database server or clients under your control, it could
|
586
|
+
# be dangerous to allow untrusted users to pass JSON sources into it.
|
587
|
+
# If you must use it, use JSON.unsafe_load instead to make it clear.
|
588
|
+
#
|
589
|
+
# Since JSON version 2.8.0, `load` emits a deprecation warning when a
|
590
|
+
# non native type is deserialized, without `create_additions` being explicitly
|
591
|
+
# enabled, and in JSON version 3.0, `load` will have `create_additions` disabled
|
592
|
+
# by default.
|
593
|
+
#
|
567
594
|
# - Argument +source+ must be, or be convertible to, a \String:
|
568
595
|
# - If +source+ responds to instance method +to_str+,
|
569
596
|
# <tt>source.to_str</tt> becomes the source.
|
@@ -578,10 +605,6 @@ module JSON
|
|
578
605
|
# - Argument +proc+, if given, must be a \Proc that accepts one argument.
|
579
606
|
# It will be called recursively with each result (depth-first order).
|
580
607
|
# See details below.
|
581
|
-
# BEWARE: This method is meant to serialise data from trusted user input,
|
582
|
-
# like from your own database server or clients under your control, it could
|
583
|
-
# be dangerous to allow untrusted users to pass JSON sources into it.
|
584
|
-
# If you must use it, use JSON.unsafe_load instead to make it clear.
|
585
608
|
# - Argument +opts+, if given, contains a \Hash of options for the parsing.
|
586
609
|
# See {Parsing Options}[#module-JSON-label-Parsing+Options].
|
587
610
|
# The default options can be changed via method JSON.load_default_options=.
|
@@ -794,18 +817,15 @@ module JSON
|
|
794
817
|
opts = opts.merge(:max_nesting => limit) if limit
|
795
818
|
opts = merge_dump_options(opts, **kwargs) if kwargs
|
796
819
|
|
797
|
-
|
798
|
-
|
820
|
+
begin
|
821
|
+
if State === opts
|
822
|
+
opts.generate(obj, anIO)
|
823
|
+
else
|
824
|
+
State.generate(obj, opts, anIO)
|
825
|
+
end
|
799
826
|
rescue JSON::NestingError
|
800
827
|
raise ArgumentError, "exceed depth limit"
|
801
828
|
end
|
802
|
-
|
803
|
-
if anIO.nil?
|
804
|
-
result
|
805
|
-
else
|
806
|
-
anIO.write result
|
807
|
-
anIO
|
808
|
-
end
|
809
829
|
end
|
810
830
|
|
811
831
|
# Encodes string using String.encode.
|
@@ -47,6 +47,17 @@ 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
|
+
|
50
61
|
# call-seq: to_h
|
51
62
|
#
|
52
63
|
# Returns the configuration instance variables as a hash, that can be
|
@@ -62,8 +62,8 @@ module JSON
|
|
62
62
|
string
|
63
63
|
end
|
64
64
|
|
65
|
-
def utf8_to_json_ascii(
|
66
|
-
string =
|
65
|
+
def utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
|
66
|
+
string = original_string.b
|
67
67
|
map = script_safe ? SCRIPT_SAFE_MAP : MAP
|
68
68
|
string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
|
69
69
|
string.gsub!(/(
|
@@ -74,7 +74,7 @@ module JSON
|
|
74
74
|
)+ |
|
75
75
|
[\x80-\xc1\xf5-\xff] # invalid
|
76
76
|
)/nx) { |c|
|
77
|
-
c.size == 1 and raise GeneratorError
|
77
|
+
c.size == 1 and raise GeneratorError.new("invalid utf8 byte: '#{c}'", original_string)
|
78
78
|
s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0]
|
79
79
|
s.force_encoding(::Encoding::BINARY)
|
80
80
|
s.gsub!(/.{4}/n, '\\\\u\&')
|
@@ -83,7 +83,7 @@ module JSON
|
|
83
83
|
string.force_encoding(::Encoding::UTF_8)
|
84
84
|
string
|
85
85
|
rescue => e
|
86
|
-
raise GeneratorError.
|
86
|
+
raise GeneratorError.new(e.message, original_string)
|
87
87
|
end
|
88
88
|
|
89
89
|
def valid_utf8?(string)
|
@@ -96,8 +96,14 @@ module JSON
|
|
96
96
|
# This class is used to create State instances, that are use to hold data
|
97
97
|
# while generating a JSON text from a Ruby data structure.
|
98
98
|
class State
|
99
|
-
def self.generate(obj, opts = nil)
|
100
|
-
new(opts).generate(obj)
|
99
|
+
def self.generate(obj, opts = nil, io = nil)
|
100
|
+
string = new(opts).generate(obj)
|
101
|
+
if io
|
102
|
+
io.write(string)
|
103
|
+
io
|
104
|
+
else
|
105
|
+
string
|
106
|
+
end
|
101
107
|
end
|
102
108
|
|
103
109
|
# Creates a State object from _opts_, which ought to be Hash to create
|
@@ -300,8 +306,10 @@ module JSON
|
|
300
306
|
else
|
301
307
|
result = obj.to_json(self)
|
302
308
|
end
|
303
|
-
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError
|
304
|
-
"source sequence #{result.inspect} is illegal/malformed utf-8"
|
309
|
+
JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new(
|
310
|
+
"source sequence #{result.inspect} is illegal/malformed utf-8",
|
311
|
+
obj
|
312
|
+
)
|
305
313
|
result
|
306
314
|
end
|
307
315
|
|
@@ -358,10 +366,10 @@ module JSON
|
|
358
366
|
begin
|
359
367
|
string = string.encode(::Encoding::UTF_8)
|
360
368
|
rescue Encoding::UndefinedConversionError => error
|
361
|
-
raise GeneratorError
|
369
|
+
raise GeneratorError.new(error.message, string)
|
362
370
|
end
|
363
371
|
end
|
364
|
-
raise GeneratorError
|
372
|
+
raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
|
365
373
|
|
366
374
|
if /["\\\x0-\x1f]/n.match?(string)
|
367
375
|
buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
|
@@ -397,7 +405,7 @@ module JSON
|
|
397
405
|
# special method #to_json was defined for some object.
|
398
406
|
def to_json(state = nil, *)
|
399
407
|
if state && State.from_state(state).strict?
|
400
|
-
raise GeneratorError
|
408
|
+
raise GeneratorError.new("#{self.class} not allowed in JSON", self)
|
401
409
|
else
|
402
410
|
to_s.to_json
|
403
411
|
end
|
@@ -448,7 +456,7 @@ module JSON
|
|
448
456
|
|
449
457
|
result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
|
450
458
|
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
451
|
-
raise GeneratorError
|
459
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
452
460
|
elsif value.respond_to?(:to_json)
|
453
461
|
result << value.to_json(state)
|
454
462
|
else
|
@@ -501,7 +509,7 @@ module JSON
|
|
501
509
|
result << delim unless first
|
502
510
|
result << state.indent * depth if indent
|
503
511
|
if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
|
504
|
-
raise GeneratorError
|
512
|
+
raise GeneratorError.new("#{value.class} not allowed in JSON", value)
|
505
513
|
elsif value.respond_to?(:to_json)
|
506
514
|
result << value.to_json(state)
|
507
515
|
else
|
@@ -530,13 +538,13 @@ module JSON
|
|
530
538
|
if state.allow_nan?
|
531
539
|
to_s
|
532
540
|
else
|
533
|
-
raise GeneratorError
|
541
|
+
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
534
542
|
end
|
535
543
|
when nan?
|
536
544
|
if state.allow_nan?
|
537
545
|
to_s
|
538
546
|
else
|
539
|
-
raise GeneratorError
|
547
|
+
raise GeneratorError.new("#{self} not allowed in JSON", self)
|
540
548
|
end
|
541
549
|
else
|
542
550
|
to_s
|
@@ -552,7 +560,7 @@ module JSON
|
|
552
560
|
state = State.from_state(state)
|
553
561
|
if encoding == ::Encoding::UTF_8
|
554
562
|
unless valid_encoding?
|
555
|
-
raise GeneratorError
|
563
|
+
raise GeneratorError.new("source sequence is illegal/malformed utf-8", self)
|
556
564
|
end
|
557
565
|
string = self
|
558
566
|
else
|
@@ -564,7 +572,7 @@ module JSON
|
|
564
572
|
%("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}")
|
565
573
|
end
|
566
574
|
rescue Encoding::UndefinedConversionError => error
|
567
|
-
raise ::JSON::GeneratorError
|
575
|
+
raise ::JSON::GeneratorError.new(error.message, self)
|
568
576
|
end
|
569
577
|
|
570
578
|
# Module that holds the extending methods if, the String module is
|
data/lib/json/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This is a JSON implementation as a Ruby extension in C.
|
14
14
|
email: flori@ping.de
|