psych 3.3.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 +1 -1
- data/Rakefile +9 -2
- data/ext/psych/yaml/loader.c +1 -1
- data/ext/psych/yaml/scanner.c +2 -2
- data/ext/psych/yaml/yaml.h +4 -4
- data/ext/psych/yaml/yaml_private.h +1 -1
- data/lib/psych/class_loader.rb +4 -4
- 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 +2 -2
- data/lib/psych/nodes/scalar.rb +1 -1
- data/lib/psych/nodes.rb +7 -7
- data/lib/psych/scalar_scanner.rb +8 -9
- 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 +12 -10
- data/lib/psych/visitors/visitor.rb +1 -1
- data/lib/psych/visitors/yaml_tree.rb +53 -5
- data/lib/psych/visitors.rb +6 -6
- data/lib/psych.rb +159 -81
- data/psych.gemspec +2 -0
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1369793b13011e838e482cd74a90f8ad91dca42331cbbd12fc9f6a9b94aec5b6
|
4
|
+
data.tar.gz: 3552d1df84ad75f3662eff7bf1d824d706304288aa253627212265d311069198
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc828b1cb2e72cb28366bfe22c3ddc320cf30723da7268af66cfef39d3f4f70310f07af224407f1e34a18ea0c00e6c6bc533299b3d20e4c7effdad00bf689e72
|
7
|
+
data.tar.gz: 4817b1702fe5fc7a659fc1156342630bee265c644074ea15859b32c8ebbb446db837bd68e004f8a1e13c11c860f67e8215fcfe4be609187e0986f2a94f102793
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -3,8 +3,8 @@ Bundler::GemHelper.install_tasks
|
|
3
3
|
|
4
4
|
require "rake/testtask"
|
5
5
|
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs << "test"
|
7
|
-
t.
|
6
|
+
t.libs << "test/lib" << "test"
|
7
|
+
t.ruby_opts << "-rhelper"
|
8
8
|
t.test_files = FileList['test/**/test_*.rb']
|
9
9
|
t.verbose = true
|
10
10
|
t.warning = true
|
@@ -31,4 +31,11 @@ else
|
|
31
31
|
Rake::ExtensionTask.new("psych")
|
32
32
|
end
|
33
33
|
|
34
|
+
task :sync_tool do
|
35
|
+
require 'fileutils'
|
36
|
+
FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
|
37
|
+
FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
|
38
|
+
FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
|
39
|
+
end
|
40
|
+
|
34
41
|
task :default => [:compile, :test]
|
data/ext/psych/yaml/loader.c
CHANGED
data/ext/psych/yaml/scanner.c
CHANGED
@@ -273,7 +273,7 @@
|
|
273
273
|
* The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
|
274
274
|
* increase that precedes a block collection (cf. the INDENT token in Python).
|
275
275
|
* The token BLOCK-END denote indentation decrease that ends a block collection
|
276
|
-
* (cf. the DEDENT token in Python). However YAML has some syntax
|
276
|
+
* (cf. the DEDENT token in Python). However YAML has some syntax peculiarities
|
277
277
|
* that makes detections of these tokens more complex.
|
278
278
|
*
|
279
279
|
* The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
|
@@ -3287,7 +3287,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
|
|
3287
3287
|
|
3288
3288
|
/* Check if we are at the end of the scalar. */
|
3289
3289
|
|
3290
|
-
/* Fix for crash
|
3290
|
+
/* Fix for crash uninitialized value crash
|
3291
3291
|
* Credit for the bug and input is to OSS Fuzz
|
3292
3292
|
* Credit for the fix to Alex Gaynor
|
3293
3293
|
*/
|
data/ext/psych/yaml/yaml.h
CHANGED
@@ -1095,7 +1095,7 @@ typedef struct yaml_parser_s {
|
|
1095
1095
|
yaml_error_type_t error;
|
1096
1096
|
/** Error description. */
|
1097
1097
|
const char *problem;
|
1098
|
-
/** The byte about which the problem
|
1098
|
+
/** The byte about which the problem occurred. */
|
1099
1099
|
size_t problem_offset;
|
1100
1100
|
/** The problematic value (@c -1 is none). */
|
1101
1101
|
int problem_value;
|
@@ -1335,7 +1335,7 @@ yaml_parser_delete(yaml_parser_t *parser);
|
|
1335
1335
|
* Set a string input.
|
1336
1336
|
*
|
1337
1337
|
* Note that the @a input pointer must be valid while the @a parser object
|
1338
|
-
* exists. The application is responsible for
|
1338
|
+
* exists. The application is responsible for destroying @a input after
|
1339
1339
|
* destroying the @a parser.
|
1340
1340
|
*
|
1341
1341
|
* @param[in,out] parser A parser object.
|
@@ -1734,7 +1734,7 @@ typedef struct yaml_emitter_s {
|
|
1734
1734
|
size_t length;
|
1735
1735
|
/** Does the scalar contain line breaks? */
|
1736
1736
|
int multiline;
|
1737
|
-
/** Can the scalar be
|
1737
|
+
/** Can the scalar be expressed in the flow plain style? */
|
1738
1738
|
int flow_plain_allowed;
|
1739
1739
|
/** Can the scalar be expressed in the block plain style? */
|
1740
1740
|
int block_plain_allowed;
|
@@ -1950,7 +1950,7 @@ yaml_emitter_close(yaml_emitter_t *emitter);
|
|
1950
1950
|
/**
|
1951
1951
|
* Emit a YAML document.
|
1952
1952
|
*
|
1953
|
-
* The
|
1953
|
+
* The document object may be generated using the yaml_parser_load() function
|
1954
1954
|
* or the yaml_document_initialize() function. The emitter takes the
|
1955
1955
|
* responsibility for the document object and destroys its content after
|
1956
1956
|
* it is emitted. The document object is destroyed even if the function fails.
|
data/lib/psych/class_loader.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
2
|
+
require_relative 'omap'
|
3
|
+
require_relative 'set'
|
4
4
|
|
5
5
|
module Psych
|
6
6
|
class ClassLoader # :nodoc:
|
@@ -86,7 +86,7 @@ module Psych
|
|
86
86
|
if @symbols.include? sym
|
87
87
|
super
|
88
88
|
else
|
89
|
-
raise DisallowedClass, 'Symbol'
|
89
|
+
raise DisallowedClass.new('load', 'Symbol')
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -96,7 +96,7 @@ module Psych
|
|
96
96
|
if @classes.include? klassname
|
97
97
|
super
|
98
98
|
else
|
99
|
-
raise DisallowedClass, klassname
|
99
|
+
raise DisallowedClass.new('load', klassname)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
data/lib/psych/core_ext.rb
CHANGED
data/lib/psych/exception.rb
CHANGED
@@ -7,8 +7,8 @@ module Psych
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class DisallowedClass < Exception
|
10
|
-
def initialize klass_name
|
11
|
-
super "Tried to
|
10
|
+
def initialize action, klass_name
|
11
|
+
super "Tried to #{action} unspecified class: #{klass_name}"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/lib/psych/handler.rb
CHANGED
@@ -119,7 +119,7 @@ module Psych
|
|
119
119
|
# +tag+ is an associated tag or nil
|
120
120
|
# +plain+ is a boolean value
|
121
121
|
# +quoted+ is a boolean value
|
122
|
-
# +style+ is an integer
|
122
|
+
# +style+ is an integer indicating the string style
|
123
123
|
#
|
124
124
|
# See the constants in Psych::Nodes::Scalar for the possible values of
|
125
125
|
# +style+
|
data/lib/psych/json/stream.rb
CHANGED
data/lib/psych/nodes/node.rb
CHANGED
data/lib/psych/nodes/scalar.rb
CHANGED
data/lib/psych/nodes.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
require_relative 'nodes/node'
|
3
|
+
require_relative 'nodes/stream'
|
4
|
+
require_relative 'nodes/document'
|
5
|
+
require_relative 'nodes/sequence'
|
6
|
+
require_relative 'nodes/scalar'
|
7
|
+
require_relative 'nodes/mapping'
|
8
|
+
require_relative 'nodes/alias'
|
9
9
|
|
10
10
|
module Psych
|
11
11
|
###
|
data/lib/psych/scalar_scanner.rb
CHANGED
@@ -9,15 +9,14 @@ 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
|
|
@@ -34,7 +33,7 @@ module Psych
|
|
34
33
|
|
35
34
|
# Check for a String type, being careful not to get caught by hash keys, hex values, and
|
36
35
|
# special floats (e.g., -.inf).
|
37
|
-
if string.match?(
|
36
|
+
if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/)
|
38
37
|
return string if string.length > 5
|
39
38
|
|
40
39
|
if string.match?(/^[^ytonf~]/i)
|
@@ -61,7 +60,7 @@ module Psych
|
|
61
60
|
rescue ArgumentError
|
62
61
|
string
|
63
62
|
end
|
64
|
-
elsif string.match?(
|
63
|
+
elsif string.match?(/^\+?\.inf$/i)
|
65
64
|
Float::INFINITY
|
66
65
|
elsif string.match?(/^-\.inf$/i)
|
67
66
|
-Float::INFINITY
|
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
|
@@ -24,6 +24,7 @@ module Psych
|
|
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
|
29
30
|
@symbolize_names = symbolize_names
|
@@ -48,7 +49,7 @@ module Psych
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def deserialize o
|
51
|
-
if klass = resolve_class(
|
52
|
+
if klass = resolve_class(@load_tags[o.tag])
|
52
53
|
instance = klass.allocate
|
53
54
|
|
54
55
|
if instance.respond_to?(:init_with)
|
@@ -128,7 +129,7 @@ module Psych
|
|
128
129
|
end
|
129
130
|
|
130
131
|
def visit_Psych_Nodes_Sequence o
|
131
|
-
if klass = resolve_class(
|
132
|
+
if klass = resolve_class(@load_tags[o.tag])
|
132
133
|
instance = klass.allocate
|
133
134
|
|
134
135
|
if instance.respond_to?(:init_with)
|
@@ -160,8 +161,8 @@ module Psych
|
|
160
161
|
end
|
161
162
|
|
162
163
|
def visit_Psych_Nodes_Mapping o
|
163
|
-
if
|
164
|
-
return revive(resolve_class(
|
164
|
+
if @load_tags[o.tag]
|
165
|
+
return revive(resolve_class(@load_tags[o.tag]), o)
|
165
166
|
end
|
166
167
|
return revive_hash(register(o, {}), o) unless o.tag
|
167
168
|
|
@@ -326,6 +327,7 @@ module Psych
|
|
326
327
|
end
|
327
328
|
|
328
329
|
private
|
330
|
+
|
329
331
|
def register node, object
|
330
332
|
@st[node.anchor] = object if node.anchor
|
331
333
|
object
|
@@ -337,7 +339,7 @@ module Psych
|
|
337
339
|
list
|
338
340
|
end
|
339
341
|
|
340
|
-
def revive_hash hash, o
|
342
|
+
def revive_hash hash, o, tagged= false
|
341
343
|
o.children.each_slice(2) { |k,v|
|
342
344
|
key = accept(k)
|
343
345
|
val = accept(v)
|
@@ -364,7 +366,7 @@ module Psych
|
|
364
366
|
hash[key] = val
|
365
367
|
end
|
366
368
|
else
|
367
|
-
if @symbolize_names
|
369
|
+
if !tagged && @symbolize_names && key.is_a?(String)
|
368
370
|
key = key.to_sym
|
369
371
|
elsif !@freeze
|
370
372
|
key = deduplicate(key)
|
@@ -402,7 +404,7 @@ module Psych
|
|
402
404
|
|
403
405
|
def revive klass, node
|
404
406
|
s = register(node, klass.allocate)
|
405
|
-
init_with(s, revive_hash({}, node), node)
|
407
|
+
init_with(s, revive_hash({}, node, true), node)
|
406
408
|
end
|
407
409
|
|
408
410
|
def init_with o, h, node
|
@@ -17,7 +17,7 @@ module Psych
|
|
17
17
|
|
18
18
|
if defined?(Ractor)
|
19
19
|
def dispatch
|
20
|
-
Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache
|
20
|
+
@dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
|
21
21
|
end
|
22
22
|
else
|
23
23
|
DISPATCH = dispatch_cache
|
@@ -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
|
@@ -272,6 +272,8 @@ module Psych
|
|
272
272
|
tag = 'tag:yaml.org,2002:str'
|
273
273
|
plain = false
|
274
274
|
quote = false
|
275
|
+
elsif o == 'y' || o == 'n'
|
276
|
+
style = Nodes::Scalar::DOUBLE_QUOTED
|
275
277
|
elsif @line_width && o.length > @line_width
|
276
278
|
style = Nodes::Scalar::FOLDED
|
277
279
|
elsif o =~ /^[^[:word:]][^"]*$/
|
@@ -509,9 +511,9 @@ module Psych
|
|
509
511
|
def emit_coder c, o
|
510
512
|
case c.type
|
511
513
|
when :scalar
|
512
|
-
@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
|
513
515
|
when :seq
|
514
|
-
@emitter.start_sequence nil, c.tag, c.tag.nil?,
|
516
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
|
515
517
|
c.seq.each do |thing|
|
516
518
|
accept thing
|
517
519
|
end
|
@@ -535,5 +537,51 @@ module Psych
|
|
535
537
|
end
|
536
538
|
end
|
537
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
|
538
586
|
end
|
539
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'
|
data/lib/psych.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
require_relative 'psych/versions'
|
3
3
|
case RUBY_ENGINE
|
4
4
|
when 'jruby'
|
5
|
-
|
5
|
+
require_relative 'psych_jars'
|
6
6
|
if JRuby::Util.respond_to?(:load_ext)
|
7
7
|
JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
|
8
8
|
else
|
@@ -12,28 +12,28 @@ when 'jruby'
|
|
12
12
|
else
|
13
13
|
require 'psych.so'
|
14
14
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
require_relative 'psych/nodes'
|
16
|
+
require_relative 'psych/streaming'
|
17
|
+
require_relative 'psych/visitors'
|
18
|
+
require_relative 'psych/handler'
|
19
|
+
require_relative 'psych/tree_builder'
|
20
|
+
require_relative 'psych/parser'
|
21
|
+
require_relative 'psych/omap'
|
22
|
+
require_relative 'psych/set'
|
23
|
+
require_relative 'psych/coder'
|
24
|
+
require_relative 'psych/core_ext'
|
25
|
+
require_relative 'psych/stream'
|
26
|
+
require_relative 'psych/json/tree_builder'
|
27
|
+
require_relative 'psych/json/stream'
|
28
|
+
require_relative 'psych/handlers/document_stream'
|
29
|
+
require_relative 'psych/class_loader'
|
30
30
|
|
31
31
|
###
|
32
32
|
# = Overview
|
33
33
|
#
|
34
34
|
# Psych is a YAML parser and emitter.
|
35
35
|
# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
|
36
|
-
# or [
|
36
|
+
# or [git repo: https://github.com/yaml/libyaml] for its YAML parsing
|
37
37
|
# and emitting capabilities. In addition to wrapping libyaml, Psych also
|
38
38
|
# knows how to serialize and de-serialize most Ruby objects to and from
|
39
39
|
# the YAML format.
|
@@ -234,9 +234,6 @@ require 'psych/class_loader'
|
|
234
234
|
module Psych
|
235
235
|
# The version of libyaml Psych is using
|
236
236
|
LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
|
237
|
-
# Deprecation guard
|
238
|
-
NOT_GIVEN = Object.new.freeze
|
239
|
-
private_constant :NOT_GIVEN
|
240
237
|
|
241
238
|
###
|
242
239
|
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
@@ -249,11 +246,11 @@ module Psych
|
|
249
246
|
#
|
250
247
|
# Example:
|
251
248
|
#
|
252
|
-
# Psych.
|
253
|
-
# Psych.
|
249
|
+
# Psych.unsafe_load("--- a") # => 'a'
|
250
|
+
# Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b']
|
254
251
|
#
|
255
252
|
# begin
|
256
|
-
# Psych.
|
253
|
+
# Psych.unsafe_load("--- `", filename: "file.txt")
|
257
254
|
# rescue Psych::SyntaxError => ex
|
258
255
|
# ex.file # => 'file.txt'
|
259
256
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
@@ -262,25 +259,21 @@ module Psych
|
|
262
259
|
# When the optional +symbolize_names+ keyword argument is set to a
|
263
260
|
# true value, returns symbols for keys in Hash objects (default: strings).
|
264
261
|
#
|
265
|
-
# Psych.
|
266
|
-
# Psych.
|
262
|
+
# Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
263
|
+
# Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
267
264
|
#
|
268
265
|
# Raises a TypeError when `yaml` parameter is NilClass
|
269
266
|
#
|
270
267
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
271
268
|
# YAML documents that are supplied via user input. Instead, please use the
|
272
|
-
# safe_load method.
|
269
|
+
# load method or the safe_load method.
|
273
270
|
#
|
274
|
-
def self.
|
275
|
-
if legacy_filename != NOT_GIVEN
|
276
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load is deprecated. Use keyword argument like Psych.load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
277
|
-
filename = legacy_filename
|
278
|
-
end
|
279
|
-
|
271
|
+
def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false
|
280
272
|
result = parse(yaml, filename: filename)
|
281
273
|
return fallback unless result
|
282
274
|
result.to_ruby(symbolize_names: symbolize_names, freeze: freeze)
|
283
275
|
end
|
276
|
+
class << self; alias :load :unsafe_load; end
|
284
277
|
|
285
278
|
###
|
286
279
|
# Safely load the yaml string in +yaml+. By default, only the following
|
@@ -289,7 +282,8 @@ module Psych
|
|
289
282
|
# * TrueClass
|
290
283
|
# * FalseClass
|
291
284
|
# * NilClass
|
292
|
-
# *
|
285
|
+
# * Integer
|
286
|
+
# * Float
|
293
287
|
# * String
|
294
288
|
# * Array
|
295
289
|
# * Hash
|
@@ -326,27 +320,7 @@ module Psych
|
|
326
320
|
# Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
327
321
|
# Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
328
322
|
#
|
329
|
-
def self.safe_load yaml,
|
330
|
-
if legacy_permitted_classes != NOT_GIVEN
|
331
|
-
warn_with_uplevel 'Passing permitted_classes with the 2nd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_classes: ...) instead.', uplevel: 1 if $VERBOSE
|
332
|
-
permitted_classes = legacy_permitted_classes
|
333
|
-
end
|
334
|
-
|
335
|
-
if legacy_permitted_symbols != NOT_GIVEN
|
336
|
-
warn_with_uplevel 'Passing permitted_symbols with the 3rd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_symbols: ...) instead.', uplevel: 1 if $VERBOSE
|
337
|
-
permitted_symbols = legacy_permitted_symbols
|
338
|
-
end
|
339
|
-
|
340
|
-
if legacy_aliases != NOT_GIVEN
|
341
|
-
warn_with_uplevel 'Passing aliases with the 4th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, aliases: ...) instead.', uplevel: 1 if $VERBOSE
|
342
|
-
aliases = legacy_aliases
|
343
|
-
end
|
344
|
-
|
345
|
-
if legacy_filename != NOT_GIVEN
|
346
|
-
warn_with_uplevel 'Passing filename with the 5th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
347
|
-
filename = legacy_filename
|
348
|
-
end
|
349
|
-
|
323
|
+
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
|
350
324
|
result = parse(yaml, filename: filename)
|
351
325
|
return fallback unless result
|
352
326
|
|
@@ -362,6 +336,46 @@ module Psych
|
|
362
336
|
result
|
363
337
|
end
|
364
338
|
|
339
|
+
###
|
340
|
+
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
341
|
+
# provided, the object contained in the first document will be returned.
|
342
|
+
# +filename+ will be used in the exception message if any exception
|
343
|
+
# is raised while parsing. If +yaml+ is empty, it returns
|
344
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
345
|
+
#
|
346
|
+
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
347
|
+
#
|
348
|
+
# Example:
|
349
|
+
#
|
350
|
+
# Psych.load("--- a") # => 'a'
|
351
|
+
# Psych.load("---\n - a\n - b") # => ['a', 'b']
|
352
|
+
#
|
353
|
+
# begin
|
354
|
+
# Psych.load("--- `", filename: "file.txt")
|
355
|
+
# rescue Psych::SyntaxError => ex
|
356
|
+
# ex.file # => 'file.txt'
|
357
|
+
# ex.message # => "(file.txt): found character that cannot start any token"
|
358
|
+
# end
|
359
|
+
#
|
360
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
361
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
362
|
+
#
|
363
|
+
# Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
|
364
|
+
# Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
365
|
+
#
|
366
|
+
# Raises a TypeError when `yaml` parameter is NilClass. This method is
|
367
|
+
# similar to `safe_load` except that `Symbol` objects are allowed by default.
|
368
|
+
#
|
369
|
+
def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
|
370
|
+
safe_load yaml, permitted_classes: permitted_classes,
|
371
|
+
permitted_symbols: permitted_symbols,
|
372
|
+
aliases: aliases,
|
373
|
+
filename: filename,
|
374
|
+
fallback: fallback,
|
375
|
+
symbolize_names: symbolize_names,
|
376
|
+
freeze: freeze
|
377
|
+
end
|
378
|
+
|
365
379
|
###
|
366
380
|
# Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document.
|
367
381
|
# +filename+ is used in the exception message if a Psych::SyntaxError is
|
@@ -381,22 +395,12 @@ module Psych
|
|
381
395
|
# end
|
382
396
|
#
|
383
397
|
# See Psych::Nodes for more information about YAML AST.
|
384
|
-
def self.parse yaml,
|
385
|
-
if legacy_filename != NOT_GIVEN
|
386
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse is deprecated. Use keyword argument like Psych.parse(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
387
|
-
filename = legacy_filename
|
388
|
-
end
|
389
|
-
|
398
|
+
def self.parse yaml, filename: nil
|
390
399
|
parse_stream(yaml, filename: filename) do |node|
|
391
400
|
return node
|
392
401
|
end
|
393
402
|
|
394
|
-
|
395
|
-
warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
|
396
|
-
fallback
|
397
|
-
else
|
398
|
-
false
|
399
|
-
end
|
403
|
+
false
|
400
404
|
end
|
401
405
|
|
402
406
|
###
|
@@ -445,12 +449,7 @@ module Psych
|
|
445
449
|
# Raises a TypeError when NilClass is passed.
|
446
450
|
#
|
447
451
|
# See Psych::Nodes for more information about YAML AST.
|
448
|
-
def self.parse_stream yaml,
|
449
|
-
if legacy_filename != NOT_GIVEN
|
450
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse_stream is deprecated. Use keyword argument like Psych.parse_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
451
|
-
filename = legacy_filename
|
452
|
-
end
|
453
|
-
|
452
|
+
def self.parse_stream yaml, filename: nil, &block
|
454
453
|
if block_given?
|
455
454
|
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
|
456
455
|
parser.parse yaml, filename
|
@@ -514,6 +513,79 @@ module Psych
|
|
514
513
|
visitor.tree.yaml io, options
|
515
514
|
end
|
516
515
|
|
516
|
+
###
|
517
|
+
# call-seq:
|
518
|
+
# Psych.safe_dump(o) -> string of yaml
|
519
|
+
# Psych.safe_dump(o, options) -> string of yaml
|
520
|
+
# Psych.safe_dump(o, io) -> io object passed in
|
521
|
+
# Psych.safe_dump(o, io, options) -> io object passed in
|
522
|
+
#
|
523
|
+
# Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
|
524
|
+
# to control the output format. If an IO object is passed in, the YAML will
|
525
|
+
# be dumped to that IO object. By default, only the following
|
526
|
+
# classes are allowed to be serialized:
|
527
|
+
#
|
528
|
+
# * TrueClass
|
529
|
+
# * FalseClass
|
530
|
+
# * NilClass
|
531
|
+
# * Integer
|
532
|
+
# * Float
|
533
|
+
# * String
|
534
|
+
# * Array
|
535
|
+
# * Hash
|
536
|
+
#
|
537
|
+
# Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
|
538
|
+
# keyword argument. They are additive. For example, to allow Date serialization:
|
539
|
+
#
|
540
|
+
# Psych.safe_dump(yaml, permitted_classes: [Date])
|
541
|
+
#
|
542
|
+
# Now the Date class can be dumped in addition to the classes listed above.
|
543
|
+
#
|
544
|
+
# A Psych::DisallowedClass exception will be raised if the object contains a
|
545
|
+
# class that isn't in the +permitted_classes+ list.
|
546
|
+
#
|
547
|
+
# Currently supported options are:
|
548
|
+
#
|
549
|
+
# [<tt>:indentation</tt>] Number of space characters used to indent.
|
550
|
+
# Acceptable value should be in <tt>0..9</tt> range,
|
551
|
+
# otherwise option is ignored.
|
552
|
+
#
|
553
|
+
# Default: <tt>2</tt>.
|
554
|
+
# [<tt>:line_width</tt>] Max character to wrap line at.
|
555
|
+
#
|
556
|
+
# Default: <tt>0</tt> (meaning "wrap at 81").
|
557
|
+
# [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
|
558
|
+
# strictly formal).
|
559
|
+
#
|
560
|
+
# Default: <tt>false</tt>.
|
561
|
+
# [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
|
562
|
+
#
|
563
|
+
# Default: <tt>false</tt>.
|
564
|
+
#
|
565
|
+
# Example:
|
566
|
+
#
|
567
|
+
# # Dump an array, get back a YAML string
|
568
|
+
# Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
|
569
|
+
#
|
570
|
+
# # Dump an array to an IO object
|
571
|
+
# Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
|
572
|
+
#
|
573
|
+
# # Dump an array with indentation set
|
574
|
+
# Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
|
575
|
+
#
|
576
|
+
# # Dump an array to an IO with indentation set
|
577
|
+
# Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
|
578
|
+
def self.safe_dump o, io = nil, options = {}
|
579
|
+
if Hash === io
|
580
|
+
options = io
|
581
|
+
io = nil
|
582
|
+
end
|
583
|
+
|
584
|
+
visitor = Psych::Visitors::RestrictedYAMLTree.create options
|
585
|
+
visitor << o
|
586
|
+
visitor.tree.yaml io, options
|
587
|
+
end
|
588
|
+
|
517
589
|
###
|
518
590
|
# Dump a list of objects as separate documents to a document stream.
|
519
591
|
#
|
@@ -551,12 +623,7 @@ module Psych
|
|
551
623
|
# end
|
552
624
|
# list # => ['foo', 'bar']
|
553
625
|
#
|
554
|
-
def self.load_stream yaml,
|
555
|
-
if legacy_filename != NOT_GIVEN
|
556
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load_stream is deprecated. Use keyword argument like Psych.load_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
557
|
-
filename = legacy_filename
|
558
|
-
end
|
559
|
-
|
626
|
+
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
|
560
627
|
result = if block_given?
|
561
628
|
parse_stream(yaml, filename: filename) do |node|
|
562
629
|
yield node.to_ruby(**kwargs)
|
@@ -577,9 +644,9 @@ module Psych
|
|
577
644
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
578
645
|
# YAML documents that are supplied via user input. Instead, please use the
|
579
646
|
# safe_load_file method.
|
580
|
-
def self.
|
647
|
+
def self.unsafe_load_file filename, **kwargs
|
581
648
|
File.open(filename, 'r:bom|utf-8') { |f|
|
582
|
-
self.
|
649
|
+
self.unsafe_load f, filename: filename, **kwargs
|
583
650
|
}
|
584
651
|
end
|
585
652
|
|
@@ -594,6 +661,17 @@ module Psych
|
|
594
661
|
}
|
595
662
|
end
|
596
663
|
|
664
|
+
###
|
665
|
+
# Loads the document contained in +filename+. Returns the yaml contained in
|
666
|
+
# +filename+ as a Ruby object, or if the file is empty, it returns
|
667
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
668
|
+
# See load for options.
|
669
|
+
def self.load_file filename, **kwargs
|
670
|
+
File.open(filename, 'r:bom|utf-8') { |f|
|
671
|
+
self.load f, filename: filename, **kwargs
|
672
|
+
}
|
673
|
+
end
|
674
|
+
|
597
675
|
# :stopdoc:
|
598
676
|
def self.add_domain_type domain, type_tag, &block
|
599
677
|
key = ['tag', domain, type_tag].join ':'
|
data/psych.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: psych
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
@@ -10,8 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
14
|
-
dependencies:
|
13
|
+
date: 2021-12-20 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: stringio
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
15
29
|
description: |
|
16
30
|
Psych is a YAML parser and emitter. Psych leverages libyaml[https://pyyaml.org/wiki/LibYAML]
|
17
31
|
for its YAML parsing and emitting capabilities. In addition to wrapping libyaml,
|
@@ -117,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
131
|
- !ruby/object:Gem::Version
|
118
132
|
version: '0'
|
119
133
|
requirements: []
|
120
|
-
rubygems_version: 3.
|
134
|
+
rubygems_version: 3.3.0.dev
|
121
135
|
signing_key:
|
122
136
|
specification_version: 4
|
123
137
|
summary: Psych is a YAML parser and emitter
|