puppet 2.7.21 → 2.7.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +14 -0
- data/Gemfile.lock +2 -2
- data/ext/build_defaults.yaml +2 -3
- data/ext/debian/control +1 -1
- data/ext/packaging/README.md +496 -8
- data/ext/packaging/spec/tasks/00_utils_spec.rb +7 -7
- data/ext/packaging/spec/tasks/build_object_spec.rb +3 -0
- data/ext/packaging/tasks/00_utils.rake +2 -2
- data/ext/packaging/tasks/10_setupvars.rake +8 -1
- data/ext/packaging/tasks/build.rake +2 -0
- data/ext/packaging/tasks/deb_repos.rake +48 -15
- data/ext/packaging/tasks/jenkins.rake +30 -2
- data/ext/packaging/tasks/mock.rake +3 -2
- data/ext/packaging/tasks/pe_remote.rake +1 -1
- data/ext/packaging/tasks/pe_ship.rake +4 -5
- data/ext/packaging/tasks/pe_sign.rake +8 -0
- data/ext/packaging/tasks/pe_sles.rake +8 -7
- data/ext/packaging/tasks/pre_tasks.rake +0 -0
- data/ext/packaging/tasks/retrieve.rake +11 -1
- data/ext/packaging/tasks/rpm_repos.rake +71 -49
- data/ext/packaging/tasks/ship.rake +14 -2
- data/ext/packaging/tasks/sign.rake +9 -3
- data/ext/packaging/tasks/tar.rake +5 -0
- data/ext/packaging/tasks/vendor_gems.rake +110 -0
- data/install.rb +1 -1
- data/lib/puppet.rb +11 -0
- data/lib/puppet/indirector/report/processor.rb +1 -1
- data/lib/puppet/indirector/report/rest.rb +7 -0
- data/lib/puppet/indirector/resource/rest.rb +9 -0
- data/lib/puppet/indirector/rest.rb +81 -47
- data/lib/puppet/indirector/run/rest.rb +6 -0
- data/lib/puppet/network/formats.rb +20 -10
- data/lib/puppet/network/http/handler.rb +1 -1
- data/lib/puppet/node.rb +25 -0
- data/lib/puppet/node/facts.rb +23 -4
- data/lib/puppet/resource.rb +2 -4
- data/lib/puppet/resource/status.rb +28 -0
- data/lib/puppet/run.rb +24 -2
- data/lib/puppet/status.rb +6 -2
- data/lib/puppet/transaction/event.rb +19 -0
- data/lib/puppet/transaction/report.rb +39 -0
- data/lib/puppet/util/log.rb +19 -0
- data/lib/puppet/util/metric.rb +6 -0
- data/lib/puppet/util/monkey_patches.rb +0 -16
- data/lib/puppet/vendor.rb +55 -0
- data/lib/puppet/vendor/load_safe_yaml.rb +1 -0
- data/lib/puppet/vendor/require_vendored.rb +4 -0
- data/lib/puppet/vendor/safe_yaml/CHANGES.md +104 -0
- data/lib/puppet/vendor/safe_yaml/Gemfile +11 -0
- data/lib/puppet/vendor/safe_yaml/LICENSE.txt +22 -0
- data/lib/puppet/vendor/safe_yaml/README.md +179 -0
- data/lib/puppet/vendor/safe_yaml/Rakefile +6 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml.rb +253 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/deep.rb +34 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/date.rb +27 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/hexadecimal.rb +12 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/parse/sexagesimal.rb +26 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/psych_handler.rb +92 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/psych_resolver.rb +52 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/resolver.rb +94 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/safe_to_ruby_visitor.rb +17 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_hack.rb +36 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_node_monkeypatch.rb +43 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/syck_resolver.rb +38 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform.rb +41 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_boolean.rb +21 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_date.rb +11 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_float.rb +33 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_integer.rb +25 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_nil.rb +18 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/to_symbol.rb +13 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/transform/transformation_map.rb +47 -0
- data/lib/puppet/vendor/safe_yaml/lib/safe_yaml/version.rb +3 -0
- data/lib/puppet/vendor/safe_yaml/run_specs_all_ruby_versions.sh +21 -0
- data/lib/puppet/vendor/safe_yaml/safe_yaml.gemspec +18 -0
- data/lib/puppet/vendor/safe_yaml/spec/exploit.1.9.2.yaml +2 -0
- data/lib/puppet/vendor/safe_yaml/spec/exploit.1.9.3.yaml +2 -0
- data/lib/puppet/vendor/safe_yaml/spec/psych_resolver_spec.rb +10 -0
- data/lib/puppet/vendor/safe_yaml/spec/resolver_specs.rb +250 -0
- data/lib/puppet/vendor/safe_yaml/spec/safe_yaml_spec.rb +702 -0
- data/lib/puppet/vendor/safe_yaml/spec/spec_helper.rb +18 -0
- data/lib/puppet/vendor/safe_yaml/spec/support/exploitable_back_door.rb +29 -0
- data/lib/puppet/vendor/safe_yaml/spec/syck_resolver_spec.rb +10 -0
- data/lib/puppet/vendor/safe_yaml/spec/transform/base64_spec.rb +11 -0
- data/lib/puppet/vendor/safe_yaml/spec/transform/to_date_spec.rb +34 -0
- data/lib/puppet/vendor/safe_yaml/spec/transform/to_float_spec.rb +42 -0
- data/lib/puppet/vendor/safe_yaml/spec/transform/to_integer_spec.rb +59 -0
- data/lib/puppet/vendor/safe_yaml/spec/transform/to_symbol_spec.rb +49 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/lib/puppet_spec/matchers.rb +8 -0
- data/spec/unit/file_serving/metadata_spec.rb +20 -28
- data/spec/unit/indirector/report/rest_spec.rb +41 -0
- data/spec/unit/indirector/rest_spec.rb +314 -339
- data/spec/unit/network/formats_spec.rb +36 -27
- data/spec/unit/network/http/handler_spec.rb +3 -12
- data/spec/unit/node_spec.rb +81 -0
- data/spec/unit/resource_spec.rb +5 -35
- data/spec/unit/run_spec.rb +22 -8
- data/spec/unit/status_spec.rb +6 -0
- data/test/network/handler/report.rb +0 -36
- metadata +148 -102
@@ -0,0 +1,34 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Deep
|
3
|
+
def self.freeze(object)
|
4
|
+
object.each do |*entry|
|
5
|
+
value = entry.last
|
6
|
+
case value
|
7
|
+
when String, Regexp
|
8
|
+
value.freeze
|
9
|
+
when Enumerable
|
10
|
+
Deep.freeze(value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
return object.freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.copy(object)
|
18
|
+
duplicate = object.dup rescue object
|
19
|
+
|
20
|
+
case object
|
21
|
+
when Array
|
22
|
+
(0...duplicate.count).each do |i|
|
23
|
+
duplicate[i] = Deep.copy(duplicate[i])
|
24
|
+
end
|
25
|
+
when Hash
|
26
|
+
duplicate.keys.each do |key|
|
27
|
+
duplicate[key] = Deep.copy(duplicate[key])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
duplicate
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Parse
|
3
|
+
class Date
|
4
|
+
# This one's easy enough :)
|
5
|
+
DATE_MATCHER = /\A(\d{4})-(\d{2})-(\d{2})\Z/.freeze
|
6
|
+
|
7
|
+
# This unbelievable little gem is taken basically straight from the YAML spec, but made
|
8
|
+
# slightly more readable (to my poor eyes at least) to me:
|
9
|
+
# http://yaml.org/type/timestamp.html
|
10
|
+
TIME_MATCHER = /\A\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d{2}:\d{2}(?:\.\d*)?\s*(?:Z|[-+]\d{1,2}(?::?\d{2})?)?\Z/.freeze
|
11
|
+
|
12
|
+
SECONDS_PER_DAY = 60 * 60 * 24
|
13
|
+
MICROSECONDS_PER_SECOND = 1000000
|
14
|
+
|
15
|
+
# So this is weird. In Ruby 1.8.7, the DateTime#sec_fraction method returned fractional
|
16
|
+
# seconds in units of DAYS for some reason. In 1.9.2, they changed the units -- much more
|
17
|
+
# reasonably -- to seconds.
|
18
|
+
SEC_FRACTION_MULTIPLIER = RUBY_VERSION == "1.8.7" ? (SECONDS_PER_DAY * MICROSECONDS_PER_SECOND) : MICROSECONDS_PER_SECOND
|
19
|
+
|
20
|
+
def self.value(value)
|
21
|
+
d = DateTime.parse(value)
|
22
|
+
usec = d.sec_fraction * SEC_FRACTION_MULTIPLIER
|
23
|
+
Time.utc(d.year, d.month, d.day, d.hour, d.min, d.sec, usec) - (d.offset * SECONDS_PER_DAY)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Parse
|
3
|
+
class Sexagesimal
|
4
|
+
INTEGER_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\Z/.freeze
|
5
|
+
FLOAT_MATCHER = /\A[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*\Z/.freeze
|
6
|
+
|
7
|
+
def self.value(value)
|
8
|
+
before_decimal, after_decimal = value.split(".")
|
9
|
+
|
10
|
+
whole_part = 0
|
11
|
+
multiplier = 1
|
12
|
+
|
13
|
+
before_decimal = before_decimal.split(":")
|
14
|
+
until before_decimal.empty?
|
15
|
+
whole_part += (Float(before_decimal.pop) * multiplier)
|
16
|
+
multiplier *= 60
|
17
|
+
end
|
18
|
+
|
19
|
+
result = whole_part
|
20
|
+
result += Float("." + after_decimal) unless after_decimal.nil?
|
21
|
+
result *= -1 if value[0] == "-"
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "psych"
|
2
|
+
require "base64"
|
3
|
+
|
4
|
+
module SafeYAML
|
5
|
+
class PsychHandler < Psych::Handler
|
6
|
+
def initialize(options)
|
7
|
+
@options = SafeYAML::OPTIONS.merge(options || {})
|
8
|
+
@initializers = @options[:custom_initializers] || {}
|
9
|
+
@anchors = {}
|
10
|
+
@stack = []
|
11
|
+
@current_key = nil
|
12
|
+
@result = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def result
|
16
|
+
@result
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_to_current_structure(value, anchor=nil, quoted=nil, tag=nil)
|
20
|
+
value = Transform.to_proper_type(value, quoted, tag, @options)
|
21
|
+
|
22
|
+
@anchors[anchor] = value if anchor
|
23
|
+
|
24
|
+
if @result.nil?
|
25
|
+
@result = value
|
26
|
+
@current_structure = @result
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
if @current_structure.respond_to?(:<<)
|
31
|
+
@current_structure << value
|
32
|
+
|
33
|
+
elsif @current_structure.respond_to?(:[]=)
|
34
|
+
if @current_key.nil?
|
35
|
+
@current_key = value
|
36
|
+
|
37
|
+
else
|
38
|
+
if @current_key == "<<"
|
39
|
+
@current_structure.merge!(value)
|
40
|
+
else
|
41
|
+
@current_structure[@current_key] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
@current_key = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
else
|
48
|
+
raise "Don't know how to add to a #{@current_structure.class}!"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def end_current_structure
|
53
|
+
@stack.pop
|
54
|
+
@current_structure = @stack.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def streaming?
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
# event handlers
|
62
|
+
def alias(anchor)
|
63
|
+
add_to_current_structure(@anchors[anchor])
|
64
|
+
end
|
65
|
+
|
66
|
+
def scalar(value, anchor, tag, plain, quoted, style)
|
67
|
+
add_to_current_structure(value, anchor, quoted, tag)
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_mapping(anchor, tag, implicit, style)
|
71
|
+
map = @initializers.include?(tag) ? @initializers[tag].call : {}
|
72
|
+
self.add_to_current_structure(map, anchor)
|
73
|
+
@current_structure = map
|
74
|
+
@stack.push(map)
|
75
|
+
end
|
76
|
+
|
77
|
+
def end_mapping
|
78
|
+
self.end_current_structure()
|
79
|
+
end
|
80
|
+
|
81
|
+
def start_sequence(anchor, tag, implicit, style)
|
82
|
+
seq = @initializers.include?(tag) ? @initializers[tag].call : []
|
83
|
+
self.add_to_current_structure(seq, anchor)
|
84
|
+
@current_structure = seq
|
85
|
+
@stack.push(seq)
|
86
|
+
end
|
87
|
+
|
88
|
+
def end_sequence
|
89
|
+
self.end_current_structure()
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class PsychResolver < Resolver
|
3
|
+
NODE_TYPES = {
|
4
|
+
Psych::Nodes::Document => :root,
|
5
|
+
Psych::Nodes::Mapping => :map,
|
6
|
+
Psych::Nodes::Sequence => :seq,
|
7
|
+
Psych::Nodes::Scalar => :scalar,
|
8
|
+
Psych::Nodes::Alias => :alias
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
super
|
13
|
+
@aliased_nodes = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def resolve_root(root)
|
17
|
+
resolve_seq(root).first
|
18
|
+
end
|
19
|
+
|
20
|
+
def resolve_alias(node)
|
21
|
+
resolve_node(@aliased_nodes[node.anchor])
|
22
|
+
end
|
23
|
+
|
24
|
+
def native_resolve(node)
|
25
|
+
@visitor ||= SafeYAML::SafeToRubyVisitor.new(self)
|
26
|
+
@visitor.accept(node)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_node_type(node)
|
30
|
+
NODE_TYPES[node.class]
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_node_tag(node)
|
34
|
+
node.tag
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_node_value(node)
|
38
|
+
@aliased_nodes[node.anchor] = node if node.respond_to?(:anchor) && node.anchor
|
39
|
+
|
40
|
+
case get_node_type(node)
|
41
|
+
when :root, :map, :seq
|
42
|
+
node.children
|
43
|
+
when :scalar
|
44
|
+
node.value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def value_is_quoted?(node)
|
49
|
+
node.quoted
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Resolver
|
3
|
+
def initialize(options)
|
4
|
+
@options = SafeYAML::OPTIONS.merge(options || {})
|
5
|
+
@whitelist = @options[:whitelisted_tags] || []
|
6
|
+
@initializers = @options[:custom_initializers] || {}
|
7
|
+
@raise_on_unknown_tag = @options[:raise_on_unknown_tag]
|
8
|
+
end
|
9
|
+
|
10
|
+
def resolve_node(node)
|
11
|
+
return node if !node
|
12
|
+
return self.native_resolve(node) if tag_is_whitelisted?(self.get_node_tag(node))
|
13
|
+
|
14
|
+
case self.get_node_type(node)
|
15
|
+
when :root
|
16
|
+
resolve_root(node)
|
17
|
+
when :map
|
18
|
+
resolve_map(node)
|
19
|
+
when :seq
|
20
|
+
resolve_seq(node)
|
21
|
+
when :scalar
|
22
|
+
resolve_scalar(node)
|
23
|
+
when :alias
|
24
|
+
resolve_alias(node)
|
25
|
+
else
|
26
|
+
raise "Don't know how to resolve this node: #{node.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def resolve_map(node)
|
31
|
+
tag = get_and_check_node_tag(node)
|
32
|
+
hash = @initializers.include?(tag) ? @initializers[tag].call : {}
|
33
|
+
map = normalize_map(self.get_node_value(node))
|
34
|
+
|
35
|
+
# Take the "<<" key nodes first, as these are meant to approximate a form of inheritance.
|
36
|
+
inheritors = map.select { |key_node, value_node| resolve_node(key_node) == "<<" }
|
37
|
+
inheritors.each do |key_node, value_node|
|
38
|
+
merge_into_hash(hash, resolve_node(value_node))
|
39
|
+
end
|
40
|
+
|
41
|
+
# All that's left should be normal (non-"<<") nodes.
|
42
|
+
(map - inheritors).each do |key_node, value_node|
|
43
|
+
hash[resolve_node(key_node)] = resolve_node(value_node)
|
44
|
+
end
|
45
|
+
|
46
|
+
return hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def resolve_seq(node)
|
50
|
+
seq = self.get_node_value(node)
|
51
|
+
|
52
|
+
tag = get_and_check_node_tag(node)
|
53
|
+
arr = @initializers.include?(tag) ? @initializers[tag].call : []
|
54
|
+
|
55
|
+
seq.inject(arr) { |array, node| array << resolve_node(node) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def resolve_scalar(node)
|
59
|
+
Transform.to_proper_type(self.get_node_value(node), self.value_is_quoted?(node), get_and_check_node_tag(node), @options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_and_check_node_tag(node)
|
63
|
+
tag = self.get_node_tag(node)
|
64
|
+
SafeYAML.tag_safety_check!(tag, @options)
|
65
|
+
tag
|
66
|
+
end
|
67
|
+
|
68
|
+
def tag_is_whitelisted?(tag)
|
69
|
+
@whitelist.include?(tag)
|
70
|
+
end
|
71
|
+
|
72
|
+
def options
|
73
|
+
@options
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def normalize_map(map)
|
78
|
+
# Syck creates Hashes from maps.
|
79
|
+
if map.is_a?(Hash)
|
80
|
+
map.inject([]) { |arr, key_and_value| arr << key_and_value }
|
81
|
+
|
82
|
+
# Psych is really weird; it flattens out a Hash completely into: [key, value, key, value, ...]
|
83
|
+
else
|
84
|
+
map.each_slice(2).to_a
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def merge_into_hash(hash, array)
|
89
|
+
array.each do |key, value|
|
90
|
+
hash[key] = value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class SafeToRubyVisitor < Psych::Visitors::ToRuby
|
3
|
+
def initialize(resolver)
|
4
|
+
super()
|
5
|
+
@resolver = resolver
|
6
|
+
end
|
7
|
+
|
8
|
+
def accept(node)
|
9
|
+
if node.tag
|
10
|
+
SafeYAML.tag_safety_check!(node.tag, @resolver.options)
|
11
|
+
return super
|
12
|
+
end
|
13
|
+
|
14
|
+
@resolver.resolve_node(node)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Hack to JRuby 1.8's YAML Parser Yecht
|
2
|
+
#
|
3
|
+
# This file is always loaded AFTER either syck or psych are already
|
4
|
+
# loaded. It then looks at what constants are available and creates
|
5
|
+
# a consistent view on all rubys.
|
6
|
+
#
|
7
|
+
# Taken from rubygems and modified.
|
8
|
+
# See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/syck_hack.rb
|
9
|
+
|
10
|
+
module YAML
|
11
|
+
# In newer 1.9.2, there is a Syck toplevel constant instead of it
|
12
|
+
# being underneith YAML. If so, reference it back under YAML as
|
13
|
+
# well.
|
14
|
+
if defined? ::Syck
|
15
|
+
# for tests that change YAML::ENGINE
|
16
|
+
# 1.8 does not support the second argument to const_defined?
|
17
|
+
remove_const :Syck rescue nil
|
18
|
+
|
19
|
+
Syck = ::Syck
|
20
|
+
|
21
|
+
# JRuby's "Syck" is called "Yecht"
|
22
|
+
elsif defined? YAML::Yecht
|
23
|
+
Syck = YAML::Yecht
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sometime in the 1.9 dev cycle, the Syck constant was moved from under YAML
|
28
|
+
# to be a toplevel constant. So gemspecs created under these versions of Syck
|
29
|
+
# will have references to Syck::DefaultKey.
|
30
|
+
#
|
31
|
+
# So we need to be sure that we reference Syck at the toplevel too so that
|
32
|
+
# we can always load these kind of gemspecs.
|
33
|
+
#
|
34
|
+
if !defined?(Syck)
|
35
|
+
Syck = YAML::Syck
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# This is, admittedly, pretty insane. Fundamentally the challenge here is this: if we want to allow
|
2
|
+
# whitelisting of tags (while still leveraging Syck's internal functionality), then we have to
|
3
|
+
# change how Syck::Node#transform works. But since we (SafeYAML) do not control instantiation of
|
4
|
+
# Syck::Node objects, we cannot, for example, subclass Syck::Node and override #tranform the "easy"
|
5
|
+
# way. So the only choice is to monkeypatch, like this. And the only way to make this work
|
6
|
+
# recursively with potentially call-specific options (that my feeble brain can think of) is to set
|
7
|
+
# pseudo-global options on the first call and unset them once the recursive stack has fully unwound.
|
8
|
+
|
9
|
+
monkeypatch = <<-EORUBY
|
10
|
+
class Node
|
11
|
+
@@safe_transform_depth = 0
|
12
|
+
@@safe_transform_whitelist = nil
|
13
|
+
|
14
|
+
def safe_transform(options={})
|
15
|
+
begin
|
16
|
+
@@safe_transform_depth += 1
|
17
|
+
@@safe_transform_whitelist ||= options[:whitelisted_tags]
|
18
|
+
|
19
|
+
if self.type_id
|
20
|
+
SafeYAML.tag_safety_check!(self.type_id, options)
|
21
|
+
return unsafe_transform if @@safe_transform_whitelist.include?(self.type_id)
|
22
|
+
end
|
23
|
+
|
24
|
+
SafeYAML::SyckResolver.new.resolve_node(self)
|
25
|
+
|
26
|
+
ensure
|
27
|
+
@@safe_transform_depth -= 1
|
28
|
+
if @@safe_transform_depth == 0
|
29
|
+
@@safe_transform_whitelist = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :unsafe_transform, :transform
|
35
|
+
alias_method :transform, :safe_transform
|
36
|
+
end
|
37
|
+
EORUBY
|
38
|
+
|
39
|
+
if defined?(YAML::Syck::Node)
|
40
|
+
YAML::Syck.module_eval monkeypatch
|
41
|
+
else
|
42
|
+
Syck.module_eval monkeypatch
|
43
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class SyckResolver < Resolver
|
3
|
+
QUOTE_STYLES = [
|
4
|
+
:quote1,
|
5
|
+
:quote2
|
6
|
+
].freeze
|
7
|
+
|
8
|
+
NODE_TYPES = {
|
9
|
+
Hash => :map,
|
10
|
+
Array => :seq,
|
11
|
+
String => :scalar
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def native_resolve(node)
|
19
|
+
node.transform(self.options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_node_type(node)
|
23
|
+
NODE_TYPES[node.value.class]
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_node_tag(node)
|
27
|
+
node.type_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_node_value(node)
|
31
|
+
node.value
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_is_quoted?(node)
|
35
|
+
QUOTE_STYLES.include?(node.instance_variable_get(:@style))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|