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,253 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
# This needs to be defined up front in case any internal classes need to base
|
4
|
+
# their behavior off of this.
|
5
|
+
module SafeYAML
|
6
|
+
YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
|
7
|
+
end
|
8
|
+
|
9
|
+
require "set"
|
10
|
+
require "safe_yaml/deep"
|
11
|
+
require "safe_yaml/parse/hexadecimal"
|
12
|
+
require "safe_yaml/parse/sexagesimal"
|
13
|
+
require "safe_yaml/parse/date"
|
14
|
+
require "safe_yaml/transform/transformation_map"
|
15
|
+
require "safe_yaml/transform/to_boolean"
|
16
|
+
require "safe_yaml/transform/to_date"
|
17
|
+
require "safe_yaml/transform/to_float"
|
18
|
+
require "safe_yaml/transform/to_integer"
|
19
|
+
require "safe_yaml/transform/to_nil"
|
20
|
+
require "safe_yaml/transform/to_symbol"
|
21
|
+
require "safe_yaml/transform"
|
22
|
+
require "safe_yaml/resolver"
|
23
|
+
require "safe_yaml/syck_hack" if defined?(JRUBY_VERSION)
|
24
|
+
|
25
|
+
module SafeYAML
|
26
|
+
MULTI_ARGUMENT_YAML_LOAD = YAML.method(:load).arity != 1
|
27
|
+
|
28
|
+
DEFAULT_OPTIONS = Deep.freeze({
|
29
|
+
:default_mode => nil,
|
30
|
+
:suppress_warnings => false,
|
31
|
+
:deserialize_symbols => false,
|
32
|
+
:whitelisted_tags => [],
|
33
|
+
:custom_initializers => {},
|
34
|
+
:raise_on_unknown_tag => false
|
35
|
+
})
|
36
|
+
|
37
|
+
OPTIONS = Deep.copy(DEFAULT_OPTIONS)
|
38
|
+
|
39
|
+
module_function
|
40
|
+
def restore_defaults!
|
41
|
+
OPTIONS.clear.merge!(Deep.copy(DEFAULT_OPTIONS))
|
42
|
+
end
|
43
|
+
|
44
|
+
def tag_safety_check!(tag, options)
|
45
|
+
return if tag.nil? || tag == "!"
|
46
|
+
if options[:raise_on_unknown_tag] && !options[:whitelisted_tags].include?(tag) && !tag_is_explicitly_trusted?(tag)
|
47
|
+
raise "Unknown YAML tag '#{tag}'"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def whitelist!(*classes)
|
52
|
+
classes.each do |klass|
|
53
|
+
whitelist_class!(klass)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def whitelist_class!(klass)
|
58
|
+
raise "#{klass} not a Class" unless klass.is_a?(::Class)
|
59
|
+
|
60
|
+
klass_name = klass.name
|
61
|
+
raise "#{klass} cannot be anonymous" if klass_name.nil? || klass_name.empty?
|
62
|
+
|
63
|
+
# Whitelist any built-in YAML tags supplied by Syck or Psych.
|
64
|
+
predefined_tag = predefined_tags[klass]
|
65
|
+
if predefined_tag
|
66
|
+
OPTIONS[:whitelisted_tags] << predefined_tag
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
# Exception is exceptional (har har).
|
71
|
+
tag_class = klass < Exception ? "exception" : "object"
|
72
|
+
|
73
|
+
tag_prefix = case YAML_ENGINE
|
74
|
+
when "psych" then "!ruby/#{tag_class}"
|
75
|
+
when "syck" then "tag:ruby.yaml.org,2002:#{tag_class}"
|
76
|
+
else raise "unknown YAML_ENGINE #{YAML_ENGINE}"
|
77
|
+
end
|
78
|
+
OPTIONS[:whitelisted_tags] << "#{tag_prefix}:#{klass_name}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def predefined_tags
|
82
|
+
if @predefined_tags.nil?
|
83
|
+
@predefined_tags = {}
|
84
|
+
|
85
|
+
if YAML_ENGINE == "syck"
|
86
|
+
YAML.tagged_classes.each do |tag, klass|
|
87
|
+
@predefined_tags[klass] = tag
|
88
|
+
end
|
89
|
+
|
90
|
+
else
|
91
|
+
# Special tags appear to be hard-coded in Psych:
|
92
|
+
# https://github.com/tenderlove/psych/blob/v1.3.4/lib/psych/visitors/to_ruby.rb
|
93
|
+
# Fortunately, there aren't many that SafeYAML doesn't already support.
|
94
|
+
@predefined_tags.merge!({
|
95
|
+
Exception => "!ruby/exception",
|
96
|
+
Range => "!ruby/range",
|
97
|
+
Regexp => "!ruby/regexp",
|
98
|
+
})
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
@predefined_tags
|
103
|
+
end
|
104
|
+
|
105
|
+
if YAML_ENGINE == "psych"
|
106
|
+
def tag_is_explicitly_trusted?(tag)
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
else
|
111
|
+
TRUSTED_TAGS = Set.new([
|
112
|
+
"tag:yaml.org,2002:binary",
|
113
|
+
"tag:yaml.org,2002:bool#no",
|
114
|
+
"tag:yaml.org,2002:bool#yes",
|
115
|
+
"tag:yaml.org,2002:float",
|
116
|
+
"tag:yaml.org,2002:float#fix",
|
117
|
+
"tag:yaml.org,2002:int",
|
118
|
+
"tag:yaml.org,2002:map",
|
119
|
+
"tag:yaml.org,2002:null",
|
120
|
+
"tag:yaml.org,2002:seq",
|
121
|
+
"tag:yaml.org,2002:str",
|
122
|
+
"tag:yaml.org,2002:timestamp",
|
123
|
+
"tag:yaml.org,2002:timestamp#ymd"
|
124
|
+
]).freeze
|
125
|
+
|
126
|
+
def tag_is_explicitly_trusted?(tag)
|
127
|
+
TRUSTED_TAGS.include?(tag)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
module YAML
|
133
|
+
def self.load_with_options(yaml, *original_arguments)
|
134
|
+
filename, options = filename_and_options_from_arguments(original_arguments)
|
135
|
+
safe_mode = safe_mode_from_options("load", options)
|
136
|
+
arguments = [yaml]
|
137
|
+
|
138
|
+
if safe_mode == :safe
|
139
|
+
arguments << filename if SafeYAML::YAML_ENGINE == "psych"
|
140
|
+
arguments << options_for_safe_load(options)
|
141
|
+
safe_load(*arguments)
|
142
|
+
else
|
143
|
+
arguments << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
|
144
|
+
unsafe_load(*arguments)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.load_file_with_options(file, options={})
|
149
|
+
safe_mode = safe_mode_from_options("load_file", options)
|
150
|
+
if safe_mode == :safe
|
151
|
+
safe_load_file(file, options_for_safe_load(options))
|
152
|
+
else
|
153
|
+
unsafe_load_file(file)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
if SafeYAML::YAML_ENGINE == "psych"
|
158
|
+
require "safe_yaml/psych_handler"
|
159
|
+
require "safe_yaml/psych_resolver"
|
160
|
+
require "safe_yaml/safe_to_ruby_visitor"
|
161
|
+
|
162
|
+
def self.safe_load(yaml, filename=nil, options={})
|
163
|
+
# If the user hasn't whitelisted any tags, we can go with this implementation which is
|
164
|
+
# significantly faster.
|
165
|
+
if (options && options[:whitelisted_tags] || SafeYAML::OPTIONS[:whitelisted_tags]).empty?
|
166
|
+
safe_handler = SafeYAML::PsychHandler.new(options)
|
167
|
+
arguments_for_parse = [yaml]
|
168
|
+
arguments_for_parse << filename if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
|
169
|
+
Psych::Parser.new(safe_handler).parse(*arguments_for_parse)
|
170
|
+
return safe_handler.result || false
|
171
|
+
|
172
|
+
else
|
173
|
+
safe_resolver = SafeYAML::PsychResolver.new(options)
|
174
|
+
tree = SafeYAML::MULTI_ARGUMENT_YAML_LOAD ?
|
175
|
+
Psych.parse(yaml, filename) :
|
176
|
+
Psych.parse(yaml)
|
177
|
+
return safe_resolver.resolve_node(tree)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.safe_load_file(filename, options={})
|
182
|
+
File.open(filename, 'r:bom|utf-8') { |f| self.safe_load(f, filename, options) }
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.unsafe_load_file(filename)
|
186
|
+
if SafeYAML::MULTI_ARGUMENT_YAML_LOAD
|
187
|
+
# https://github.com/tenderlove/psych/blob/v1.3.2/lib/psych.rb#L296-298
|
188
|
+
File.open(filename, 'r:bom|utf-8') { |f| self.unsafe_load(f, filename) }
|
189
|
+
else
|
190
|
+
# https://github.com/tenderlove/psych/blob/v1.2.2/lib/psych.rb#L231-233
|
191
|
+
self.unsafe_load File.open(filename)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
else
|
196
|
+
require "safe_yaml/syck_resolver"
|
197
|
+
require "safe_yaml/syck_node_monkeypatch"
|
198
|
+
|
199
|
+
def self.safe_load(yaml, options={})
|
200
|
+
resolver = SafeYAML::SyckResolver.new(SafeYAML::OPTIONS.merge(options || {}))
|
201
|
+
tree = YAML.parse(yaml)
|
202
|
+
return resolver.resolve_node(tree)
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.safe_load_file(filename, options={})
|
206
|
+
File.open(filename) { |f| self.safe_load(f, options) }
|
207
|
+
end
|
208
|
+
|
209
|
+
def self.unsafe_load_file(filename)
|
210
|
+
# https://github.com/indeyets/syck/blob/master/ext/ruby/lib/yaml.rb#L133-135
|
211
|
+
File.open(filename) { |f| self.unsafe_load(f) }
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class << self
|
216
|
+
alias_method :unsafe_load, :load
|
217
|
+
alias_method :load, :load_with_options
|
218
|
+
alias_method :load_file, :load_file_with_options
|
219
|
+
|
220
|
+
private
|
221
|
+
def filename_and_options_from_arguments(arguments)
|
222
|
+
if arguments.count == 1
|
223
|
+
if arguments.first.is_a?(String)
|
224
|
+
return arguments.first, {}
|
225
|
+
else
|
226
|
+
return nil, arguments.first || {}
|
227
|
+
end
|
228
|
+
|
229
|
+
else
|
230
|
+
return arguments.first, arguments.last || {}
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def safe_mode_from_options(method, options={})
|
235
|
+
if options[:safe].nil?
|
236
|
+
safe_mode = SafeYAML::OPTIONS[:default_mode] || :safe
|
237
|
+
if SafeYAML::OPTIONS[:default_mode].nil? && !SafeYAML::OPTIONS[:suppress_warnings]
|
238
|
+
Kernel.warn "Called '#{method}' without the :safe option -- defaulting to #{safe_mode} mode."
|
239
|
+
SafeYAML::OPTIONS[:suppress_warnings] = true
|
240
|
+
end
|
241
|
+
return safe_mode
|
242
|
+
end
|
243
|
+
|
244
|
+
options[:safe] ? :safe : :unsafe
|
245
|
+
end
|
246
|
+
|
247
|
+
def options_for_safe_load(base_options)
|
248
|
+
options = base_options.dup
|
249
|
+
options.delete(:safe)
|
250
|
+
options
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -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
|