Skip to content

Commit 27b7c73

Browse files
joshcooperCiprian Badescu
authored andcommitted
(PUP-11321) Allow loading of safe classes from the persistence store
The result of a deferred function is stored in the persistence store as the last known "system_value". When calling the `binary_file` function deferred, we stored a `Puppet::Pops::Types::PBinaryType::Binary` object, but failed to load it the next time we ran. Expand the list of allowed classes to include objects that may be called by builtin or custom functions.
1 parent 762f788 commit 27b7c73

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

lib/puppet/transaction/persistence.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66
# as calculating corrective_change).
77
# @api private
88
class Puppet::Transaction::Persistence
9+
10+
def self.allowed_classes
11+
@allowed_classes ||= [
12+
Symbol,
13+
Time,
14+
Regexp,
15+
# URI is excluded, because it serializes all instance variables including the
16+
# URI parser. Better to serialize the URL encoded representation.
17+
SemanticPuppet::Version,
18+
# SemanticPuppet::VersionRange has many nested classes and is unlikely to be
19+
# used directly, so ignore it
20+
Puppet::Pops::Time::Timestamp,
21+
Puppet::Pops::Time::TimeData,
22+
Puppet::Pops::Time::Timespan,
23+
Puppet::Pops::Types::PBinaryType::Binary,
24+
# Puppet::Pops::Types::PSensitiveType::Sensitive values are excluded from
25+
# the persistence store, ignore it.
26+
].freeze
27+
end
28+
929
def initialize
1030
@old_data = {}
1131
@new_data = {"resources" => {}}
@@ -62,7 +82,7 @@ def load
6282
result = nil
6383
Puppet::Util.benchmark(:debug, _("Loaded transaction store file in %{seconds} seconds")) do
6484
begin
65-
result = Puppet::Util::Yaml.safe_load_file(filename, [Symbol, Time])
85+
result = Puppet::Util::Yaml.safe_load_file(filename, self.class.allowed_classes)
6686
rescue Puppet::Util::Yaml::YamlLoadError => detail
6787
Puppet.log_exception(detail, _("Transaction store file %{filename} is corrupt (%{detail}); replacing") % { filename: filename, detail: detail })
6888

spec/unit/transaction/persistence_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,57 @@ def write_state_file(contents)
138138
persistence = Puppet::Transaction::Persistence.new
139139
expect(persistence.load.dig("File[/tmp/audit]", "parameters", "mtime", "system_value")).to contain_exactly(be_a(Time))
140140
end
141+
142+
it 'should load Regexp' do
143+
write_state_file(<<~END)
144+
system_value:
145+
- !ruby/regexp /regexp/
146+
END
147+
148+
persistence = Puppet::Transaction::Persistence.new
149+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Regexp))
150+
end
151+
152+
it 'should load semantic puppet version' do
153+
write_state_file(<<~END)
154+
system_value:
155+
- !ruby/object:SemanticPuppet::Version
156+
major: 1
157+
minor: 0
158+
patch: 0
159+
prerelease:
160+
build:
161+
END
162+
163+
persistence = Puppet::Transaction::Persistence.new
164+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(SemanticPuppet::Version))
165+
end
166+
167+
it 'should load puppet time related objects' do
168+
write_state_file(<<~END)
169+
system_value:
170+
- !ruby/object:Puppet::Pops::Time::Timestamp
171+
nsecs: 1638316135955087259
172+
- !ruby/object:Puppet::Pops::Time::TimeData
173+
nsecs: 1495789430910161286
174+
- !ruby/object:Puppet::Pops::Time::Timespan
175+
nsecs: 1495789430910161286
176+
END
177+
178+
persistence = Puppet::Transaction::Persistence.new
179+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Time::Timestamp), be_a(Puppet::Pops::Time::TimeData), be_a(Puppet::Pops::Time::Timespan))
180+
end
181+
182+
it 'should load binary objects' do
183+
write_state_file(<<~END)
184+
system_value:
185+
- !ruby/object:Puppet::Pops::Types::PBinaryType::Binary
186+
binary_buffer: ''
187+
END
188+
189+
persistence = Puppet::Transaction::Persistence.new
190+
expect(persistence.load.dig("system_value")).to contain_exactly(be_a(Puppet::Pops::Types::PBinaryType::Binary))
191+
end
141192
end
142193
end
143194

0 commit comments

Comments
 (0)