From 412fffa1c851899cdf5b137a8442d0c17dc9e778 Mon Sep 17 00:00:00 2001 From: Abdullah Yousuf <23.abdullah.y@gmail.com> Date: Wed, 13 Oct 2021 20:03:37 -0400 Subject: [PATCH] made background invocation operator use -WorkingDirectory to set working directory of new job and added a testto ensure background job script block does not use Set-Location to set working directory --- .../engine/runtime/Operations/MiscOps.cs | 19 +++++++++++-------- .../Microsoft.PowerShell.Core/Job.Tests.ps1 | 6 +++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs index 8d50fcf5f1aa..fdb01a3b19c4 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs @@ -531,12 +531,8 @@ private static string GetParameterText(string parameterName) var pipelineOffset = pipelineAst.Extent.StartOffset; var variables = pipelineAst.FindAll(static x => x is VariableExpressionAst, true); - // Used to make sure that the job runs in the current directory - const string cmdPrefix = @"Microsoft.PowerShell.Management\Set-Location -LiteralPath $using:pwd ; "; - // Minimize allocations by initializing the stringbuilder to the size of the source string + prefix + space for ${using:} * 2 - System.Text.StringBuilder updatedScriptblock = new System.Text.StringBuilder(cmdPrefix.Length + scriptblockBodyString.Length + 18); - updatedScriptblock.Append(cmdPrefix); + System.Text.StringBuilder updatedScriptblock = new System.Text.StringBuilder(scriptblockBodyString.Length + 18); int position = 0; // Prefix variables in the scriptblock with $using: @@ -568,15 +564,22 @@ private static string GetParameterText(string parameterName) var sb = ScriptBlock.Create(updatedScriptblock.ToString()); var commandInfo = new CmdletInfo("Start-Job", typeof(StartJobCommand)); commandProcessor = context.CommandDiscovery.LookupCommandProcessor(commandInfo, CommandOrigin.Internal, false, context.EngineSessionState); - var parameter = CommandParameterInternal.CreateParameterWithArgument( + var workingDirectoryParameter = CommandParameterInternal.CreateParameterWithArgument( + parameterAst: pipelineAst, + "WorkingDirectory", + null, + argumentAst: pipelineAst, + context.SessionState.Path.CurrentLocation.Path, + false); + var scriptBlockParameter = CommandParameterInternal.CreateParameterWithArgument( parameterAst: pipelineAst, "ScriptBlock", null, argumentAst: pipelineAst, sb, false); - commandProcessor.AddParameter(parameter); - pipelineProcessor.Add(commandProcessor); + commandProcessor.AddParameter(workingDirectoryParameter); + commandProcessor.AddParameter(scriptBlockParameter); pipelineProcessor.LinkPipelineSuccessOutput(outputPipe ?? new Pipe(new List())); context.PushPipelineProcessor(pipelineProcessor); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Job.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Job.Tests.ps1 index 06d84230dce1..c6c7c73974d3 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/Job.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Job.Tests.ps1 @@ -178,7 +178,7 @@ Describe "Debug-job test" -Tag "Feature" { } } -Describe "Ampersand background test" -Tag "CI","Slow" { +Describe "Ampersand background test" -Tag "CI", "Slow" { Context "Simple background job" { AfterEach { Get-Job | Remove-Job -Force @@ -218,6 +218,10 @@ Describe "Ampersand background test" -Tag "CI","Slow" { $j = Get-Location | ForEach-Object -MemberName Path & Receive-Job -Wait $j | Should -Be ($PWD.Path) } + It "Make sure Set-Location is not used in the job's script block to set the working directory" { + $j = (get-variable -value ExecutionContext).SessionState.PSVariable.Get("MyInvocation").Value.MyCommand.ScriptBlock & + (Receive-Job -Wait $j).ToString() | Should -BeExactly "(get-variable -value ExecutionContext).SessionState.PSVariable.Get(`"MyInvocation`").Value.MyCommand.ScriptBlock" + } It "Test that output redirection is done in the background job" { $j = Write-Output hello > $TESTDRIVE/hello.txt & Receive-Job -Wait $j | Should -BeNullOrEmpty