From 7296cce9c9fcff4d8f54b430c84a2290e57c8d05 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Wed, 12 Jun 2024 16:26:40 -0700 Subject: [PATCH] Check for nil before closing Uniquefile On Windows, we by default assign stdout for the child process to a file: stdout = Puppet::FileSystem::Uniquefile.new('puppet') However, if TMPDIR, TEMP or TMP env vars refer to a non-existent directory, then `Uniquefile.new` will raise, leaving `stdout` set to nil, so the later call to `stdout.close` raised NoMethodError. So check for nil before closing. We don't have this issue on posix, because it uses an IO pipe instead of Uniquefile. Fixes #9385 --- lib/puppet/util/execution.rb | 2 +- spec/unit/util/execution_spec.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/puppet/util/execution.rb b/lib/puppet/util/execution.rb index e0b116f658b..c8673d2525b 100644 --- a/lib/puppet/util/execution.rb +++ b/lib/puppet/util/execution.rb @@ -323,7 +323,7 @@ def self.execute(command, options = NoOptionsSpecified) unless options[:squelch] # if we opened a pipe, we need to clean it up. reader.close if reader - stdout.close! if Puppet::Util::Platform.windows? + stdout.close! if stdout && Puppet::Util::Platform.windows? end end diff --git a/spec/unit/util/execution_spec.rb b/spec/unit/util/execution_spec.rb index d95e3566367..9c4b9f8cac4 100644 --- a/spec/unit/util/execution_spec.rb +++ b/spec/unit/util/execution_spec.rb @@ -834,6 +834,15 @@ def expect_cwd_to_be(cwd) Puppet::Util::Execution.execute('test command') end + + it "should raise if it fails to create a Uniquefile for stdout" do + allow(Puppet::FileSystem::Uniquefile).to receive(:new) + .and_raise(Errno::ENOENT, 'C:\Users\ADMINI~1\AppData\Local\Temp\doesnotexist') + + expect { + Puppet::Util::Execution.execute('test command') + }.to raise_error(Errno::ENOENT, 'No such file or directory - C:\Users\ADMINI~1\AppData\Local\Temp\doesnotexist') + end end it "should raise an error if failonfail is true and the child failed" do