puppet 3.2.1 → 3.2.2
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/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 +8 -0
- data/lib/puppet/indirector/rest.rb +80 -52
- 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 +1 -1
- 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 +40 -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 -15
- data/lib/puppet/vendor.rb +55 -0
- data/lib/puppet/vendor/load_safe_yaml.rb +1 -0
- data/lib/puppet/vendor/require_vendored.rb +5 -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/vendor/safe_yaml_patches.rb +9 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/lib/puppet_spec/matchers.rb +8 -0
- data/spec/unit/application/facts_spec.rb +1 -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 +307 -334
- 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 +14 -0
- data/spec/unit/resource_spec.rb +5 -35
- data/spec/unit/run_spec.rb +25 -6
- data/spec/unit/status_spec.rb +6 -0
- metadata +2566 -2521
@@ -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
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module SafeYAML
|
4
|
+
class Transform
|
5
|
+
TRANSFORMERS = [
|
6
|
+
Transform::ToSymbol.new,
|
7
|
+
Transform::ToInteger.new,
|
8
|
+
Transform::ToFloat.new,
|
9
|
+
Transform::ToNil.new,
|
10
|
+
Transform::ToBoolean.new,
|
11
|
+
Transform::ToDate.new
|
12
|
+
]
|
13
|
+
|
14
|
+
def self.to_guessed_type(value, quoted=false, options=nil)
|
15
|
+
return value if quoted
|
16
|
+
|
17
|
+
if value.is_a?(String)
|
18
|
+
TRANSFORMERS.each do |transformer|
|
19
|
+
success, transformed_value = transformer.method(:transform?).arity == 1 ?
|
20
|
+
transformer.transform?(value) :
|
21
|
+
transformer.transform?(value, options)
|
22
|
+
|
23
|
+
return transformed_value if success
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
value
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.to_proper_type(value, quoted=false, tag=nil, options=nil)
|
31
|
+
case tag
|
32
|
+
when "tag:yaml.org,2002:binary", "x-private:binary", "!binary"
|
33
|
+
decoded = Base64.decode64(value)
|
34
|
+
decoded = decoded.force_encoding(value.encoding) if decoded.respond_to?(:force_encoding)
|
35
|
+
decoded
|
36
|
+
else
|
37
|
+
self.to_guessed_type(value, quoted, options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Transform
|
3
|
+
class ToBoolean
|
4
|
+
include TransformationMap
|
5
|
+
|
6
|
+
set_predefined_values({
|
7
|
+
"yes" => true,
|
8
|
+
"on" => true,
|
9
|
+
"true" => true,
|
10
|
+
"no" => false,
|
11
|
+
"off" => false,
|
12
|
+
"false" => false
|
13
|
+
})
|
14
|
+
|
15
|
+
def transform?(value)
|
16
|
+
return false if value.length > 5
|
17
|
+
return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Transform
|
3
|
+
class ToDate
|
4
|
+
def transform?(value)
|
5
|
+
return true, Date.parse(value) if Parse::Date::DATE_MATCHER.match(value)
|
6
|
+
return true, Parse::Date.value(value) if Parse::Date::TIME_MATCHER.match(value)
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Transform
|
3
|
+
class ToFloat
|
4
|
+
Infinity = 1.0 / 0.0
|
5
|
+
NaN = 0.0 / 0.0
|
6
|
+
|
7
|
+
PREDEFINED_VALUES = {
|
8
|
+
".inf" => Infinity,
|
9
|
+
".Inf" => Infinity,
|
10
|
+
".INF" => Infinity,
|
11
|
+
"-.inf" => -Infinity,
|
12
|
+
"-.Inf" => -Infinity,
|
13
|
+
"-.INF" => -Infinity,
|
14
|
+
".nan" => NaN,
|
15
|
+
".NaN" => NaN,
|
16
|
+
".NAN" => NaN,
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
MATCHER = /\A[-+]?(?:\d[\d_]*)?\.[\d_]+(?:[eE][-+][\d]+)?\Z/.freeze
|
20
|
+
|
21
|
+
def transform?(value)
|
22
|
+
return true, Float(value) if MATCHER.match(value)
|
23
|
+
try_edge_cases?(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def try_edge_cases?(value)
|
27
|
+
return true, PREDEFINED_VALUES[value] if PREDEFINED_VALUES.include?(value)
|
28
|
+
return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::FLOAT_MATCHER.match(value)
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Transform
|
3
|
+
class ToInteger
|
4
|
+
MATCHERS = Deep.freeze([
|
5
|
+
/\A[-+]?(0|([1-9][0-9_,]*))\Z/, # decimal
|
6
|
+
/\A0[0-7]+\Z/, # octal
|
7
|
+
/\A0x[0-9a-f]+\Z/i, # hexadecimal
|
8
|
+
/\A0b[01_]+\Z/ # binary
|
9
|
+
])
|
10
|
+
|
11
|
+
def transform?(value)
|
12
|
+
MATCHERS.each do |matcher|
|
13
|
+
return true, Integer(value.gsub(",", "")) if matcher.match(value)
|
14
|
+
end
|
15
|
+
try_edge_cases?(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def try_edge_cases?(value)
|
19
|
+
return true, Parse::Hexadecimal.value(value) if Parse::Hexadecimal::MATCHER.match(value)
|
20
|
+
return true, Parse::Sexagesimal.value(value) if Parse::Sexagesimal::INTEGER_MATCHER.match(value)
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SafeYAML
|
2
|
+
class Transform
|
3
|
+
class ToNil
|
4
|
+
include TransformationMap
|
5
|
+
|
6
|
+
set_predefined_values({
|
7
|
+
"" => nil,
|
8
|
+
"~" => nil,
|
9
|
+
"null" => nil,
|
10
|
+
})
|
11
|
+
|
12
|
+
def transform?(value)
|
13
|
+
return false if value.length > 4
|
14
|
+
return PREDEFINED_VALUES.include?(value), PREDEFINED_VALUES[value]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|