From 1df07b28939628d96a26f3d781829442a44e98d3 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Fri, 1 Mar 2024 12:13:53 -0800 Subject: [PATCH] Fetch the registry value not the type Facter's product release resolver called `Win32::Registry#each` and incorrectly assumed the second parameter was the `value`, when actually it was the `type`. Note the `each` method is an alias for `each_value`, which yields three parameters: `name`, `type` and `value`[1]` The issue wasn't noticed because the code also called `Win32::Registry#[]` to get the value and the tests incorrectly stubbed the Windows registry behavior. Commit 2c291fea6acb assumed the second parameter was the `value`, as a result the `os.windows` facts had a value of 1, which corresponds to `REG_SZ`[2]: C:\> facter -j os.windows "os.windows": { "edition_id": 1, .. } This isn't the first time we've had problems with overstubbing in facter, see 6e7970e20a, 86048b561a, 58185501e9 Fixes #2683 [1] https://github.com/ruby/ruby/blob/v3_2_3/ext/win32/lib/win32/registry.rb#L579 [2] https://github.com/ruby/ruby/blob/v3_2_3/ext/win32/lib/win32/registry.rb#L114 --- lib/facter/resolvers/windows/product_release.rb | 2 +- .../resolvers/windows/product_release_spec.rb | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/facter/resolvers/windows/product_release.rb b/lib/facter/resolvers/windows/product_release.rb index ce5907b96c..177ffe7cab 100644 --- a/lib/facter/resolvers/windows/product_release.rb +++ b/lib/facter/resolvers/windows/product_release.rb @@ -23,7 +23,7 @@ def read_fact_from_registry(fact_name) end def build_fact_list(reg) - reg.each do |name, value| + reg.each do |name, _type, value| case name when 'EditionID' @fact_list[:edition_id] = value diff --git a/spec/facter/resolvers/windows/product_release_spec.rb b/spec/facter/resolvers/windows/product_release_spec.rb index 290c980e95..f0c8f1e0a5 100644 --- a/spec/facter/resolvers/windows/product_release_spec.rb +++ b/spec/facter/resolvers/windows/product_release_spec.rb @@ -8,17 +8,19 @@ let(:prod) { 'Windows Server 2022 Standard' } let(:release) { '1809' } let(:display_version) { '21H2' } + # https://github.com/ruby/ruby/blob/6da8f04e01fd85e54a641c6ec4816153b9557095/ext/win32/lib/win32/registry.rb#L114 + let(:reg_sz) { 1 } before do allow(Win32::Registry::HKEY_LOCAL_MACHINE).to receive(:open) .with('SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion') .and_return(reg) allow(reg).to receive(:each) - .and_yield('EditionID', ed) - .and_yield('InstallationType', install) - .and_yield('ProductName', prod) - .and_yield('ReleaseId', release) - .and_yield('DisplayVersion', display_version) + .and_yield('EditionID', reg_sz, ed) + .and_yield('InstallationType', reg_sz, install) + .and_yield('ProductName', reg_sz, prod) + .and_yield('ReleaseId', reg_sz, release) + .and_yield('DisplayVersion', reg_sz, display_version) allow(reg).to receive(:close) end @@ -79,7 +81,7 @@ .with('SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion') .and_return(reg) allow(reg).to receive(:each) - .and_yield('ReleaseId', release) + .and_yield('ReleaseId', reg_sz, release) allow(reg).to receive(:close) end