psych 3.1.0 → 5.2.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/CONTRIBUTING.md +24 -0
- data/{ext/psych/yaml/LICENSE → LICENSE} +9 -7
- data/README.md +22 -17
- data/ext/psych/depend +14 -0
- data/ext/psych/extconf.rb +42 -28
- data/ext/psych/psych.c +6 -4
- data/ext/psych/psych_emitter.c +155 -121
- data/ext/psych/psych_parser.c +274 -302
- data/ext/psych/psych_to_ruby.c +0 -1
- data/ext/psych/psych_yaml_tree.c +0 -13
- data/lib/psych/class_loader.rb +10 -8
- data/lib/psych/core_ext.rb +1 -1
- data/lib/psych/exception.rb +16 -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 +5 -5
- data/lib/psych/nodes/scalar.rb +1 -1
- data/lib/psych/nodes.rb +7 -7
- data/lib/psych/parser.rb +13 -0
- data/lib/psych/scalar_scanner.rb +39 -47
- data/lib/psych/syntax_error.rb +1 -1
- data/lib/psych/tree_builder.rb +3 -3
- data/lib/psych/versions.rb +3 -3
- data/lib/psych/visitors/json_tree.rb +1 -1
- data/lib/psych/visitors/to_ruby.rb +60 -26
- data/lib/psych/visitors/visitor.rb +17 -3
- data/lib/psych/visitors/yaml_tree.rb +103 -71
- data/lib/psych/visitors.rb +6 -6
- data/lib/psych.rb +260 -138
- metadata +20 -53
- data/.gitignore +0 -16
- data/.travis.yml +0 -22
- data/CHANGELOG.rdoc +0 -583
- data/Gemfile +0 -3
- data/Mavenfile +0 -7
- data/Rakefile +0 -48
- data/bin/console +0 -7
- data/bin/setup +0 -6
- data/ext/psych/yaml/api.c +0 -1393
- data/ext/psych/yaml/config.h +0 -10
- data/ext/psych/yaml/dumper.c +0 -394
- data/ext/psych/yaml/emitter.c +0 -2324
- data/ext/psych/yaml/loader.c +0 -444
- data/ext/psych/yaml/parser.c +0 -1370
- data/ext/psych/yaml/reader.c +0 -469
- data/ext/psych/yaml/scanner.c +0 -3578
- data/ext/psych/yaml/writer.c +0 -141
- data/ext/psych/yaml/yaml.h +0 -1971
- data/ext/psych/yaml/yaml_private.h +0 -688
- data/psych.gemspec +0 -75
@@ -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
|
@@ -15,30 +15,25 @@ module Psych
|
|
15
15
|
class YAMLTree < Psych::Visitors::Visitor
|
16
16
|
class Registrar # :nodoc:
|
17
17
|
def initialize
|
18
|
-
@obj_to_id = {}
|
19
|
-
@obj_to_node = {}
|
20
|
-
@targets = []
|
18
|
+
@obj_to_id = {}.compare_by_identity
|
19
|
+
@obj_to_node = {}.compare_by_identity
|
21
20
|
@counter = 0
|
22
21
|
end
|
23
22
|
|
24
23
|
def register target, node
|
25
|
-
|
26
|
-
@targets << target
|
27
|
-
@obj_to_node[target.object_id] = node
|
24
|
+
@obj_to_node[target] = node
|
28
25
|
end
|
29
26
|
|
30
27
|
def key? target
|
31
|
-
@obj_to_node.key? target
|
32
|
-
rescue NoMethodError
|
33
|
-
false
|
28
|
+
@obj_to_node.key? target
|
34
29
|
end
|
35
30
|
|
36
31
|
def id_for target
|
37
|
-
@obj_to_id[target
|
32
|
+
@obj_to_id[target] ||= (@counter += 1)
|
38
33
|
end
|
39
34
|
|
40
35
|
def node_for target
|
41
|
-
@obj_to_node[target
|
36
|
+
@obj_to_node[target]
|
42
37
|
end
|
43
38
|
end
|
44
39
|
|
@@ -70,6 +65,7 @@ module Psych
|
|
70
65
|
fail(ArgumentError, "Invalid line_width #{@line_width}, must be non-negative or -1 for unlimited.")
|
71
66
|
end
|
72
67
|
end
|
68
|
+
@stringify_names = options[:stringify_names]
|
73
69
|
@coders = []
|
74
70
|
|
75
71
|
@dispatch_cache = Hash.new do |h,klass|
|
@@ -80,7 +76,7 @@ module Psych
|
|
80
76
|
raise(TypeError, "Can't dump #{target.class}") unless method
|
81
77
|
|
82
78
|
h[klass] = method
|
83
|
-
end
|
79
|
+
end.compare_by_identity
|
84
80
|
end
|
85
81
|
|
86
82
|
def start encoding = Nodes::Stream::UTF8
|
@@ -181,53 +177,24 @@ module Psych
|
|
181
177
|
end
|
182
178
|
|
183
179
|
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
|
180
|
+
dump_exception o, o.message.to_s
|
200
181
|
end
|
201
182
|
|
202
183
|
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
|
184
|
+
dump_exception o, o.message.to_s
|
219
185
|
end
|
220
186
|
|
221
187
|
def visit_Regexp o
|
222
188
|
register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
|
223
189
|
end
|
224
190
|
|
191
|
+
def visit_Date o
|
192
|
+
register o, visit_Integer(o.gregorian)
|
193
|
+
end
|
194
|
+
|
225
195
|
def visit_DateTime o
|
226
|
-
|
227
|
-
|
228
|
-
else
|
229
|
-
o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
|
230
|
-
end
|
196
|
+
t = o.italy
|
197
|
+
formatted = format_time t, t.offset.zero?
|
231
198
|
tag = '!ruby/object:DateTime'
|
232
199
|
register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
|
233
200
|
end
|
@@ -265,7 +232,6 @@ module Psych
|
|
265
232
|
end
|
266
233
|
alias :visit_TrueClass :visit_Integer
|
267
234
|
alias :visit_FalseClass :visit_Integer
|
268
|
-
alias :visit_Date :visit_Integer
|
269
235
|
|
270
236
|
def visit_Float o
|
271
237
|
if o.nan?
|
@@ -295,18 +261,20 @@ module Psych
|
|
295
261
|
style = Nodes::Scalar::LITERAL
|
296
262
|
plain = false
|
297
263
|
quote = false
|
298
|
-
elsif o
|
264
|
+
elsif o.match?(/\n(?!\Z)/) # match \n except blank line at the end of string
|
299
265
|
style = Nodes::Scalar::LITERAL
|
300
266
|
elsif o == '<<'
|
301
267
|
style = Nodes::Scalar::SINGLE_QUOTED
|
302
268
|
tag = 'tag:yaml.org,2002:str'
|
303
269
|
plain = false
|
304
270
|
quote = false
|
271
|
+
elsif o == 'y' || o == 'Y' || o == 'n' || o == 'N'
|
272
|
+
style = Nodes::Scalar::DOUBLE_QUOTED
|
305
273
|
elsif @line_width && o.length > @line_width
|
306
274
|
style = Nodes::Scalar::FOLDED
|
307
|
-
elsif o
|
275
|
+
elsif o.match?(/^[^[:word:]][^"]*$/)
|
308
276
|
style = Nodes::Scalar::DOUBLE_QUOTED
|
309
|
-
elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]
|
277
|
+
elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o)
|
310
278
|
style = Nodes::Scalar::SINGLE_QUOTED
|
311
279
|
end
|
312
280
|
|
@@ -356,7 +324,7 @@ module Psych
|
|
356
324
|
if o.class == ::Hash
|
357
325
|
register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK))
|
358
326
|
o.each do |k,v|
|
359
|
-
accept k
|
327
|
+
accept(@stringify_names && Symbol === k ? k.to_s : k)
|
360
328
|
accept v
|
361
329
|
end
|
362
330
|
@emitter.end_mapping
|
@@ -369,7 +337,7 @@ module Psych
|
|
369
337
|
register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK))
|
370
338
|
|
371
339
|
o.each do |k,v|
|
372
|
-
accept k
|
340
|
+
accept(@stringify_names && Symbol === k ? k.to_s : k)
|
373
341
|
accept v
|
374
342
|
end
|
375
343
|
|
@@ -458,15 +426,6 @@ module Psych
|
|
458
426
|
node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
|
459
427
|
register(o, node)
|
460
428
|
|
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
429
|
# Dump the ivars
|
471
430
|
accept 'ivars'
|
472
431
|
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
|
@@ -476,6 +435,15 @@ module Psych
|
|
476
435
|
end
|
477
436
|
@emitter.end_mapping
|
478
437
|
|
438
|
+
# Dump the elements
|
439
|
+
accept 'elements'
|
440
|
+
@emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
|
441
|
+
o.each do |k,v|
|
442
|
+
accept k
|
443
|
+
accept v
|
444
|
+
end
|
445
|
+
@emitter.end_mapping
|
446
|
+
|
479
447
|
@emitter.end_mapping
|
480
448
|
else
|
481
449
|
tag = "!ruby/hash:#{o.class}"
|
@@ -492,8 +460,26 @@ module Psych
|
|
492
460
|
def dump_list o
|
493
461
|
end
|
494
462
|
|
495
|
-
def
|
496
|
-
|
463
|
+
def dump_exception o, msg
|
464
|
+
tag = ['!ruby/exception', o.class.name].join ':'
|
465
|
+
|
466
|
+
@emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
|
467
|
+
|
468
|
+
if msg
|
469
|
+
@emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY
|
470
|
+
accept msg
|
471
|
+
end
|
472
|
+
|
473
|
+
@emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY
|
474
|
+
accept o.backtrace
|
475
|
+
|
476
|
+
dump_ivars o
|
477
|
+
|
478
|
+
@emitter.end_mapping
|
479
|
+
end
|
480
|
+
|
481
|
+
def format_time time, utc = time.utc?
|
482
|
+
if utc
|
497
483
|
time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
|
498
484
|
else
|
499
485
|
time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
|
@@ -521,9 +507,9 @@ module Psych
|
|
521
507
|
def emit_coder c, o
|
522
508
|
case c.type
|
523
509
|
when :scalar
|
524
|
-
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false,
|
510
|
+
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
|
525
511
|
when :seq
|
526
|
-
@emitter.start_sequence nil, c.tag, c.tag.nil?,
|
512
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
|
527
513
|
c.seq.each do |thing|
|
528
514
|
accept thing
|
529
515
|
end
|
@@ -547,5 +533,51 @@ module Psych
|
|
547
533
|
end
|
548
534
|
end
|
549
535
|
end
|
536
|
+
|
537
|
+
class RestrictedYAMLTree < YAMLTree
|
538
|
+
DEFAULT_PERMITTED_CLASSES = {
|
539
|
+
TrueClass => true,
|
540
|
+
FalseClass => true,
|
541
|
+
NilClass => true,
|
542
|
+
Integer => true,
|
543
|
+
Float => true,
|
544
|
+
String => true,
|
545
|
+
Array => true,
|
546
|
+
Hash => true,
|
547
|
+
}.compare_by_identity.freeze
|
548
|
+
|
549
|
+
def initialize emitter, ss, options
|
550
|
+
super
|
551
|
+
@permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
|
552
|
+
Array(options[:permitted_classes]).each do |klass|
|
553
|
+
@permitted_classes[klass] = true
|
554
|
+
end
|
555
|
+
@permitted_symbols = {}.compare_by_identity
|
556
|
+
Array(options[:permitted_symbols]).each do |symbol|
|
557
|
+
@permitted_symbols[symbol] = true
|
558
|
+
end
|
559
|
+
@aliases = options.fetch(:aliases, false)
|
560
|
+
end
|
561
|
+
|
562
|
+
def accept target
|
563
|
+
if !@aliases && @st.key?(target)
|
564
|
+
raise BadAlias, "Tried to dump an aliased object"
|
565
|
+
end
|
566
|
+
|
567
|
+
unless Symbol === target || @permitted_classes[target.class]
|
568
|
+
raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
|
569
|
+
end
|
570
|
+
|
571
|
+
super
|
572
|
+
end
|
573
|
+
|
574
|
+
def visit_Symbol sym
|
575
|
+
unless @permitted_classes[Symbol] || @permitted_symbols[sym]
|
576
|
+
raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
|
577
|
+
end
|
578
|
+
|
579
|
+
super
|
580
|
+
end
|
581
|
+
end
|
550
582
|
end
|
551
583
|
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'
|