From 2d1cf03cb7bf69a886444bed04db80e52c9c7acc Mon Sep 17 00:00:00 2001 From: Glenn Sarti Date: Mon, 19 Nov 2018 13:24:54 +0800 Subject: [PATCH] (PUP-9312) Don't fail entirely if one value is invalid TODO --- lib/puppet/provider/package/windows/package.rb | 4 +++- lib/puppet/util/windows/registry.rb | 18 +++++++++++++----- spec/integration/util/windows/registry_spec.rb | 7 ++++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/puppet/provider/package/windows/package.rb b/lib/puppet/provider/package/windows/package.rb index 6dc9113411e..1a11eb9d7d0 100644 --- a/lib/puppet/provider/package/windows/package.rb +++ b/lib/puppet/provider/package/windows/package.rb @@ -37,7 +37,9 @@ def self.with_key(&block) open(hive, 'Software\Microsoft\Windows\CurrentVersion\Uninstall', mode) do |uninstall| each_key(uninstall) do |name, wtime| open(hive, "#{uninstall.keyname}\\#{name}", mode) do |key| - yield key, values(key) + # Ignore invalid values so that we can continue to enumerate other packages in the run + # The `valid?` methods in the derived classes will determine if the package is actually valid + yield key, values(key, true) end end end diff --git a/lib/puppet/util/windows/registry.rb b/lib/puppet/util/windows/registry.rb index 0d689cebe69..6a69d45d304 100644 --- a/lib/puppet/util/windows/registry.rb +++ b/lib/puppet/util/windows/registry.rb @@ -59,21 +59,29 @@ def delete_key(key, subkey_name, mode = KEY64) reg_delete_key_ex(key, subkey_name, mode) end - def values(key) + def values(key, ignore_invalid_values = false) vals = {} - each_value(key) { |subkey, type, data| vals[subkey] = data } + each_value(key, ignore_invalid_values) { |subkey, type, data| vals[subkey] = data } vals end - def each_value(key, &block) + def each_value(key, ignore_invalid_values = false, &block) index = 0 subkey = nil _, value_max_len = reg_query_info_key_max_lengths(key) begin - subkey, type, data = reg_enum_value(key, index, value_max_len) - yield subkey, type, data if !subkey.nil? + begin + subkey, type, data = reg_enum_value(key, index, value_max_len) + yield subkey, type, data if !subkey.nil? + rescue Exception => ex + if ignore_invalid_values + Puppet.debug "Error while enumerating registry value #{key.keyname}, value index #{index} - #{ex.inspect}" + else + raise + end + end index += 1 end while !subkey.nil? diff --git a/spec/integration/util/windows/registry_spec.rb b/spec/integration/util/windows/registry_spec.rb index 43e6dc57d9c..cd7cd61c4ae 100644 --- a/spec/integration/util/windows/registry_spec.rb +++ b/spec/integration/util/windows/registry_spec.rb @@ -90,17 +90,18 @@ def write_corrupt_dword(reg, valuename) context "#values" do let(:key) { stub('uninstall') } + let(:ignore_invalid_values) { false } def expects_registry_value(array) key.expects(:each_value).never - subject.expects(:each_value).with(key).multiple_yields(array) + subject.expects(:each_value).with(key, ignore_invalid_values).multiple_yields(array) subject.values(key).first[1] end it "should return each value's name and data" do key.expects(:each_value).never - subject.expects(:each_value).with(key).multiple_yields( + subject.expects(:each_value).with(key, ignore_invalid_values).multiple_yields( ['string', 1, 'foo'], ['dword', 4, 0] ) expect(subject.values(key)).to eq({ 'string' => 'foo', 'dword' => 0 }) @@ -108,7 +109,7 @@ def expects_registry_value(array) it "should return an empty hash if there are no values" do key.expects(:each_value).never - subject.expects(:each_value).with(key) + subject.expects(:each_value).with(key, ignore_invalid_values) expect(subject.values(key)).to eq({}) end