psych 3.1.0 → 4.0.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/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +2 -5
- data/Rakefile +8 -15
- data/ext/psych/depend +2 -0
- data/ext/psych/extconf.rb +6 -2
- data/ext/psych/psych.c +6 -3
- data/ext/psych/psych_parser.c +20 -33
- data/ext/psych/psych_yaml_tree.c +0 -12
- data/ext/psych/yaml/api.c +22 -22
- data/ext/psych/yaml/config.h +76 -6
- data/ext/psych/yaml/dumper.c +1 -1
- data/ext/psych/yaml/emitter.c +44 -10
- data/ext/psych/yaml/loader.c +206 -106
- data/ext/psych/yaml/parser.c +6 -1
- data/ext/psych/yaml/scanner.c +45 -25
- data/ext/psych/yaml/yaml.h +43 -29
- data/ext/psych/yaml/yaml_private.h +4 -4
- data/lib/psych/class_loader.rb +10 -8
- data/lib/psych/core_ext.rb +1 -1
- data/lib/psych/exception.rb +2 -2
- data/lib/psych/handler.rb +1 -1
- data/lib/psych/handlers/document_stream.rb +1 -1
- data/lib/psych/handlers/recorder.rb +1 -1
- data/lib/psych/json/stream.rb +2 -2
- data/lib/psych/json/tree_builder.rb +1 -1
- data/lib/psych/nodes/node.rb +4 -4
- data/lib/psych/nodes/scalar.rb +1 -1
- data/lib/psych/nodes.rb +7 -7
- data/lib/psych/scalar_scanner.rb +25 -39
- data/lib/psych/syntax_error.rb +1 -1
- data/lib/psych/tree_builder.rb +1 -1
- data/lib/psych/versions.rb +3 -3
- data/lib/psych/visitors/json_tree.rb +1 -1
- data/lib/psych/visitors/to_ruby.rb +53 -20
- data/lib/psych/visitors/visitor.rb +17 -3
- data/lib/psych/visitors/yaml_tree.rb +83 -47
- data/lib/psych/visitors.rb +6 -6
- data/lib/psych.rb +222 -122
- data/psych.gemspec +10 -16
- metadata +12 -43
- data/.travis.yml +0 -22
- data/CHANGELOG.rdoc +0 -583
data/lib/psych/scalar_scanner.rb
CHANGED
@@ -9,21 +9,19 @@ module Psych
|
|
9
9
|
TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
|
10
10
|
|
11
11
|
# Taken from http://yaml.org/type/float.html
|
12
|
-
|
13
|
-
|
14
|
-
|\.(nan|NaN|NAN)(?# not a number))$/x
|
12
|
+
# Base 60, [-+]inf and NaN are handled separately
|
13
|
+
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x
|
15
14
|
|
16
15
|
# Taken from http://yaml.org/type/int.html
|
17
|
-
INTEGER = /^(?:[-+]?0b[0-1_]+
|
18
|
-
|[-+]?0[0-7_]+
|
19
|
-
|[-+]?(?:0|[1-9][0-
|
20
|
-
|[-+]?0x[0-9a-fA-F_]+
|
16
|
+
INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2)
|
17
|
+
|[-+]?0[0-7_,]+ (?# base 8)
|
18
|
+
|[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10)
|
19
|
+
|[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x
|
21
20
|
|
22
21
|
attr_reader :class_loader
|
23
22
|
|
24
23
|
# Create a new scanner
|
25
24
|
def initialize class_loader
|
26
|
-
@string_cache = {}
|
27
25
|
@symbol_cache = {}
|
28
26
|
@class_loader = class_loader
|
29
27
|
end
|
@@ -31,81 +29,70 @@ module Psych
|
|
31
29
|
# Tokenize +string+ returning the Ruby object
|
32
30
|
def tokenize string
|
33
31
|
return nil if string.empty?
|
34
|
-
return string if @string_cache.key?(string)
|
35
32
|
return @symbol_cache[string] if @symbol_cache.key?(string)
|
36
33
|
|
37
|
-
case string
|
38
34
|
# Check for a String type, being careful not to get caught by hash keys, hex values, and
|
39
35
|
# special floats (e.g., -.inf).
|
40
|
-
|
41
|
-
if string.length > 5
|
42
|
-
@string_cache[string] = true
|
43
|
-
return string
|
44
|
-
end
|
36
|
+
if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/)
|
37
|
+
return string if string.length > 5
|
45
38
|
|
46
|
-
|
47
|
-
when /^[^ytonf~]/i
|
48
|
-
@string_cache[string] = true
|
39
|
+
if string.match?(/^[^ytonf~]/i)
|
49
40
|
string
|
50
|
-
|
41
|
+
elsif string == '~' || string.match?(/^null$/i)
|
51
42
|
nil
|
52
|
-
|
43
|
+
elsif string.match?(/^(yes|true|on)$/i)
|
53
44
|
true
|
54
|
-
|
45
|
+
elsif string.match?(/^(no|false|off)$/i)
|
55
46
|
false
|
56
47
|
else
|
57
|
-
@string_cache[string] = true
|
58
48
|
string
|
59
49
|
end
|
60
|
-
|
50
|
+
elsif string.match?(TIME)
|
61
51
|
begin
|
62
52
|
parse_time string
|
63
53
|
rescue ArgumentError
|
64
54
|
string
|
65
55
|
end
|
66
|
-
|
56
|
+
elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/)
|
67
57
|
require 'date'
|
68
58
|
begin
|
69
59
|
class_loader.date.strptime(string, '%Y-%m-%d')
|
70
60
|
rescue ArgumentError
|
71
61
|
string
|
72
62
|
end
|
73
|
-
|
63
|
+
elsif string.match?(/^\+?\.inf$/i)
|
74
64
|
Float::INFINITY
|
75
|
-
|
65
|
+
elsif string.match?(/^-\.inf$/i)
|
76
66
|
-Float::INFINITY
|
77
|
-
|
67
|
+
elsif string.match?(/^\.nan$/i)
|
78
68
|
Float::NAN
|
79
|
-
|
69
|
+
elsif string.match?(/^:./)
|
80
70
|
if string =~ /^:(["'])(.*)\1/
|
81
71
|
@symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, ''))
|
82
72
|
else
|
83
73
|
@symbol_cache[string] = class_loader.symbolize(string.sub(/^:/, ''))
|
84
74
|
end
|
85
|
-
|
75
|
+
elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}$/)
|
86
76
|
i = 0
|
87
77
|
string.split(':').each_with_index do |n,e|
|
88
78
|
i += (n.to_i * 60 ** (e - 2).abs)
|
89
79
|
end
|
90
80
|
i
|
91
|
-
|
81
|
+
elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}\.[0-9_]*$/)
|
92
82
|
i = 0
|
93
83
|
string.split(':').each_with_index do |n,e|
|
94
84
|
i += (n.to_f * 60 ** (e - 2).abs)
|
95
85
|
end
|
96
86
|
i
|
97
|
-
|
98
|
-
if string
|
99
|
-
@string_cache[string] = true
|
87
|
+
elsif string.match?(FLOAT)
|
88
|
+
if string.match?(/\A[-+]?\.\Z/)
|
100
89
|
string
|
101
90
|
else
|
102
91
|
Float(string.gsub(/[,_]|\.([Ee]|$)/, '\1'))
|
103
92
|
end
|
93
|
+
elsif string.match?(INTEGER)
|
94
|
+
parse_int string
|
104
95
|
else
|
105
|
-
int = parse_int string.gsub(/[,_]/, '')
|
106
|
-
return int if int
|
107
|
-
|
108
|
-
@string_cache[string] = true
|
109
96
|
string
|
110
97
|
end
|
111
98
|
end
|
@@ -113,8 +100,7 @@ module Psych
|
|
113
100
|
###
|
114
101
|
# Parse and return an int from +string+
|
115
102
|
def parse_int string
|
116
|
-
|
117
|
-
Integer(string)
|
103
|
+
Integer(string.gsub(/[,_]/, ''))
|
118
104
|
end
|
119
105
|
|
120
106
|
###
|
data/lib/psych/syntax_error.rb
CHANGED
data/lib/psych/tree_builder.rb
CHANGED
data/lib/psych/versions.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
|
2
1
|
# frozen_string_literal: true
|
2
|
+
|
3
3
|
module Psych
|
4
4
|
# The version of Psych you are using
|
5
|
-
VERSION = '
|
5
|
+
VERSION = '4.0.3'
|
6
6
|
|
7
7
|
if RUBY_ENGINE == 'jruby'
|
8
|
-
DEFAULT_SNAKEYAML_VERSION = '1.
|
8
|
+
DEFAULT_SNAKEYAML_VERSION = '1.28'.freeze
|
9
9
|
end
|
10
10
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require_relative '../scalar_scanner'
|
3
|
+
require_relative '../class_loader'
|
4
|
+
require_relative '../exception'
|
5
5
|
|
6
6
|
unless defined?(Regexp::NOENCODING)
|
7
7
|
Regexp::NOENCODING = 32
|
@@ -12,39 +12,44 @@ module Psych
|
|
12
12
|
###
|
13
13
|
# This class walks a YAML AST, converting each node to Ruby
|
14
14
|
class ToRuby < Psych::Visitors::Visitor
|
15
|
-
def self.create
|
15
|
+
def self.create(symbolize_names: false, freeze: false)
|
16
16
|
class_loader = ClassLoader.new
|
17
17
|
scanner = ScalarScanner.new class_loader
|
18
|
-
new(scanner, class_loader)
|
18
|
+
new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze)
|
19
19
|
end
|
20
20
|
|
21
21
|
attr_reader :class_loader
|
22
22
|
|
23
|
-
def initialize ss, class_loader
|
23
|
+
def initialize ss, class_loader, symbolize_names: false, freeze: false
|
24
24
|
super()
|
25
25
|
@st = {}
|
26
26
|
@ss = ss
|
27
|
+
@load_tags = Psych.load_tags
|
27
28
|
@domain_types = Psych.domain_types
|
28
29
|
@class_loader = class_loader
|
30
|
+
@symbolize_names = symbolize_names
|
31
|
+
@freeze = freeze
|
29
32
|
end
|
30
33
|
|
31
34
|
def accept target
|
32
35
|
result = super
|
33
|
-
return result if @domain_types.empty? || !target.tag
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
+
unless @domain_types.empty? || !target.tag
|
38
|
+
key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
|
39
|
+
key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
if @domain_types.key? key
|
42
|
+
value, block = @domain_types[key]
|
43
|
+
result = block.call value, result
|
44
|
+
end
|
41
45
|
end
|
42
46
|
|
47
|
+
result = deduplicate(result).freeze if @freeze
|
43
48
|
result
|
44
49
|
end
|
45
50
|
|
46
51
|
def deserialize o
|
47
|
-
if klass = resolve_class(
|
52
|
+
if klass = resolve_class(@load_tags[o.tag])
|
48
53
|
instance = klass.allocate
|
49
54
|
|
50
55
|
if instance.respond_to?(:init_with)
|
@@ -124,7 +129,7 @@ module Psych
|
|
124
129
|
end
|
125
130
|
|
126
131
|
def visit_Psych_Nodes_Sequence o
|
127
|
-
if klass = resolve_class(
|
132
|
+
if klass = resolve_class(@load_tags[o.tag])
|
128
133
|
instance = klass.allocate
|
129
134
|
|
130
135
|
if instance.respond_to?(:init_with)
|
@@ -156,8 +161,8 @@ module Psych
|
|
156
161
|
end
|
157
162
|
|
158
163
|
def visit_Psych_Nodes_Mapping o
|
159
|
-
if
|
160
|
-
return revive(resolve_class(
|
164
|
+
if @load_tags[o.tag]
|
165
|
+
return revive(resolve_class(@load_tags[o.tag]), o)
|
161
166
|
end
|
162
167
|
return revive_hash(register(o, {}), o) unless o.tag
|
163
168
|
|
@@ -252,6 +257,8 @@ module Psych
|
|
252
257
|
|
253
258
|
e = build_exception((resolve_class($1) || class_loader.exception),
|
254
259
|
h.delete('message'))
|
260
|
+
|
261
|
+
e.set_backtrace h.delete('backtrace') if h.key? 'backtrace'
|
255
262
|
init_with(e, h, o)
|
256
263
|
|
257
264
|
when '!set', 'tag:yaml.org,2002:set'
|
@@ -320,6 +327,7 @@ module Psych
|
|
320
327
|
end
|
321
328
|
|
322
329
|
private
|
330
|
+
|
323
331
|
def register node, object
|
324
332
|
@st[node.anchor] = object if node.anchor
|
325
333
|
object
|
@@ -331,13 +339,12 @@ module Psych
|
|
331
339
|
list
|
332
340
|
end
|
333
341
|
|
334
|
-
|
335
|
-
def revive_hash hash, o
|
342
|
+
def revive_hash hash, o, tagged= false
|
336
343
|
o.children.each_slice(2) { |k,v|
|
337
344
|
key = accept(k)
|
338
345
|
val = accept(v)
|
339
346
|
|
340
|
-
if key ==
|
347
|
+
if key == '<<' && k.tag != "tag:yaml.org,2002:str"
|
341
348
|
case v
|
342
349
|
when Nodes::Alias, Nodes::Mapping
|
343
350
|
begin
|
@@ -359,6 +366,12 @@ module Psych
|
|
359
366
|
hash[key] = val
|
360
367
|
end
|
361
368
|
else
|
369
|
+
if !tagged && @symbolize_names && key.is_a?(String)
|
370
|
+
key = key.to_sym
|
371
|
+
elsif !@freeze
|
372
|
+
key = deduplicate(key)
|
373
|
+
end
|
374
|
+
|
362
375
|
hash[key] = val
|
363
376
|
end
|
364
377
|
|
@@ -366,12 +379,32 @@ module Psych
|
|
366
379
|
hash
|
367
380
|
end
|
368
381
|
|
382
|
+
if RUBY_VERSION < '2.7'
|
383
|
+
def deduplicate key
|
384
|
+
if key.is_a?(String)
|
385
|
+
# It is important to untaint the string, otherwise it won't
|
386
|
+
# be deduplicated into an fstring, but simply frozen.
|
387
|
+
-(key.untaint)
|
388
|
+
else
|
389
|
+
key
|
390
|
+
end
|
391
|
+
end
|
392
|
+
else
|
393
|
+
def deduplicate key
|
394
|
+
if key.is_a?(String)
|
395
|
+
-key
|
396
|
+
else
|
397
|
+
key
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
369
402
|
def merge_key hash, key, val
|
370
403
|
end
|
371
404
|
|
372
405
|
def revive klass, node
|
373
406
|
s = register(node, klass.allocate)
|
374
|
-
init_with(s, revive_hash({}, node), node)
|
407
|
+
init_with(s, revive_hash({}, node, true), node)
|
375
408
|
end
|
376
409
|
|
377
410
|
def init_with o, h, node
|
@@ -8,12 +8,26 @@ module Psych
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
# @api private
|
12
|
+
def self.dispatch_cache
|
13
|
+
Hash.new do |hash, klass|
|
14
|
+
hash[klass] = :"visit_#{klass.name.gsub('::', '_')}"
|
15
|
+
end.compare_by_identity
|
16
|
+
end
|
17
|
+
|
18
|
+
if defined?(Ractor)
|
19
|
+
def dispatch
|
20
|
+
@dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
DISPATCH = dispatch_cache
|
24
|
+
def dispatch
|
25
|
+
DISPATCH
|
26
|
+
end
|
13
27
|
end
|
14
28
|
|
15
29
|
def visit target
|
16
|
-
send
|
30
|
+
send dispatch[target.class], target
|
17
31
|
end
|
18
32
|
end
|
19
33
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require_relative '../tree_builder'
|
3
|
+
require_relative '../scalar_scanner'
|
4
|
+
require_relative '../class_loader'
|
5
5
|
|
6
6
|
module Psych
|
7
7
|
module Visitors
|
@@ -80,7 +80,7 @@ module Psych
|
|
80
80
|
raise(TypeError, "Can't dump #{target.class}") unless method
|
81
81
|
|
82
82
|
h[klass] = method
|
83
|
-
end
|
83
|
+
end.compare_by_identity
|
84
84
|
end
|
85
85
|
|
86
86
|
def start encoding = Nodes::Stream::UTF8
|
@@ -181,41 +181,11 @@ module Psych
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def visit_Exception o
|
184
|
-
|
185
|
-
|
186
|
-
@emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
|
187
|
-
|
188
|
-
{
|
189
|
-
'message' => private_iv_get(o, 'mesg'),
|
190
|
-
'backtrace' => private_iv_get(o, 'backtrace'),
|
191
|
-
}.each do |k,v|
|
192
|
-
next unless v
|
193
|
-
@emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
|
194
|
-
accept v
|
195
|
-
end
|
196
|
-
|
197
|
-
dump_ivars o
|
198
|
-
|
199
|
-
@emitter.end_mapping
|
184
|
+
dump_exception o, o.message.to_s
|
200
185
|
end
|
201
186
|
|
202
187
|
def visit_NameError o
|
203
|
-
|
204
|
-
|
205
|
-
@emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
|
206
|
-
|
207
|
-
{
|
208
|
-
'message' => o.message.to_s,
|
209
|
-
'backtrace' => private_iv_get(o, 'backtrace'),
|
210
|
-
}.each do |k,v|
|
211
|
-
next unless v
|
212
|
-
@emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
|
213
|
-
accept v
|
214
|
-
end
|
215
|
-
|
216
|
-
dump_ivars o
|
217
|
-
|
218
|
-
@emitter.end_mapping
|
188
|
+
dump_exception o, o.message.to_s
|
219
189
|
end
|
220
190
|
|
221
191
|
def visit_Regexp o
|
@@ -302,6 +272,8 @@ module Psych
|
|
302
272
|
tag = 'tag:yaml.org,2002:str'
|
303
273
|
plain = false
|
304
274
|
quote = false
|
275
|
+
elsif o == 'y' || o == 'n'
|
276
|
+
style = Nodes::Scalar::DOUBLE_QUOTED
|
305
277
|
elsif @line_width && o.length > @line_width
|
306
278
|
style = Nodes::Scalar::FOLDED
|
307
279
|
elsif o =~ /^[^[:word:]][^"]*$/
|
@@ -458,15 +430,6 @@ module Psych
|
|
458
430
|
node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
|
459
431
|
register(o, node)
|
460
432
|
|
461
|
-
# Dump the elements
|
462
|
-
accept 'elements'
|
463
|
-
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
|
464
|
-
o.each do |k,v|
|
465
|
-
accept k
|
466
|
-
accept v
|
467
|
-
end
|
468
|
-
@emitter.end_mapping
|
469
|
-
|
470
433
|
# Dump the ivars
|
471
434
|
accept 'ivars'
|
472
435
|
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
|
@@ -476,6 +439,15 @@ module Psych
|
|
476
439
|
end
|
477
440
|
@emitter.end_mapping
|
478
441
|
|
442
|
+
# Dump the elements
|
443
|
+
accept 'elements'
|
444
|
+
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
|
445
|
+
o.each do |k,v|
|
446
|
+
accept k
|
447
|
+
accept v
|
448
|
+
end
|
449
|
+
@emitter.end_mapping
|
450
|
+
|
479
451
|
@emitter.end_mapping
|
480
452
|
else
|
481
453
|
tag = "!ruby/hash:#{o.class}"
|
@@ -492,6 +464,24 @@ module Psych
|
|
492
464
|
def dump_list o
|
493
465
|
end
|
494
466
|
|
467
|
+
def dump_exception o, msg
|
468
|
+
tag = ['!ruby/exception', o.class.name].join ':'
|
469
|
+
|
470
|
+
@emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
|
471
|
+
|
472
|
+
if msg
|
473
|
+
@emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY
|
474
|
+
accept msg
|
475
|
+
end
|
476
|
+
|
477
|
+
@emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY
|
478
|
+
accept o.backtrace
|
479
|
+
|
480
|
+
dump_ivars o
|
481
|
+
|
482
|
+
@emitter.end_mapping
|
483
|
+
end
|
484
|
+
|
495
485
|
def format_time time
|
496
486
|
if time.utc?
|
497
487
|
time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
|
@@ -521,9 +511,9 @@ module Psych
|
|
521
511
|
def emit_coder c, o
|
522
512
|
case c.type
|
523
513
|
when :scalar
|
524
|
-
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false,
|
514
|
+
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
|
525
515
|
when :seq
|
526
|
-
@emitter.start_sequence nil, c.tag, c.tag.nil?,
|
516
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
|
527
517
|
c.seq.each do |thing|
|
528
518
|
accept thing
|
529
519
|
end
|
@@ -547,5 +537,51 @@ module Psych
|
|
547
537
|
end
|
548
538
|
end
|
549
539
|
end
|
540
|
+
|
541
|
+
class RestrictedYAMLTree < YAMLTree
|
542
|
+
DEFAULT_PERMITTED_CLASSES = {
|
543
|
+
TrueClass => true,
|
544
|
+
FalseClass => true,
|
545
|
+
NilClass => true,
|
546
|
+
Integer => true,
|
547
|
+
Float => true,
|
548
|
+
String => true,
|
549
|
+
Array => true,
|
550
|
+
Hash => true,
|
551
|
+
}.compare_by_identity.freeze
|
552
|
+
|
553
|
+
def initialize emitter, ss, options
|
554
|
+
super
|
555
|
+
@permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
|
556
|
+
Array(options[:permitted_classes]).each do |klass|
|
557
|
+
@permitted_classes[klass] = true
|
558
|
+
end
|
559
|
+
@permitted_symbols = {}.compare_by_identity
|
560
|
+
Array(options[:permitted_symbols]).each do |symbol|
|
561
|
+
@permitted_symbols[symbol] = true
|
562
|
+
end
|
563
|
+
@aliases = options.fetch(:aliases, false)
|
564
|
+
end
|
565
|
+
|
566
|
+
def accept target
|
567
|
+
if !@aliases && @st.key?(target)
|
568
|
+
raise BadAlias, "Tried to dump an aliased object"
|
569
|
+
end
|
570
|
+
|
571
|
+
unless @permitted_classes[target.class]
|
572
|
+
raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
|
573
|
+
end
|
574
|
+
|
575
|
+
super
|
576
|
+
end
|
577
|
+
|
578
|
+
def visit_Symbol sym
|
579
|
+
unless @permitted_symbols[sym]
|
580
|
+
raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
|
581
|
+
end
|
582
|
+
|
583
|
+
super
|
584
|
+
end
|
585
|
+
end
|
550
586
|
end
|
551
587
|
end
|
data/lib/psych/visitors.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
require_relative 'visitors/visitor'
|
3
|
+
require_relative 'visitors/to_ruby'
|
4
|
+
require_relative 'visitors/emitter'
|
5
|
+
require_relative 'visitors/yaml_tree'
|
6
|
+
require_relative 'visitors/json_tree'
|
7
|
+
require_relative 'visitors/depth_first'
|