From abb1de27809111ce21858f7a917f5d6d1e578802 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Thu, 22 May 2025 06:14:56 +1000 Subject: [PATCH] win coverage - Fix untrusted coverage collection (#85197) Fixes the logic when running a module through App Control when the module is not trusted to run in Full Language Mode. This ensures coverage will still run as expected and that the trust verification only happens in the wrappers that actually run/prepare the code. Also expands on a comment to clarify why only that branch is set to set the internal file encoding to UTF-8. (cherry picked from commit 17cee7a9829869ecb3070fb3b17576b44406eeb4) --- .../executor/powershell/coverage_wrapper.ps1 | 21 +++++++++++++------ .../executor/powershell/module_wrapper.ps1 | 4 +++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/ansible/executor/powershell/coverage_wrapper.ps1 b/lib/ansible/executor/powershell/coverage_wrapper.ps1 index 775f6485305..d2421d7ae69 100644 --- a/lib/ansible/executor/powershell/coverage_wrapper.ps1 +++ b/lib/ansible/executor/powershell/coverage_wrapper.ps1 @@ -28,8 +28,12 @@ $Host.Runspace.Debugger.SetDebugMode([DebugModes]::RemoteScript) Function New-CoverageBreakpointsForScriptBlock { Param ( [Parameter(Mandatory)] - [ScriptBlock] - $ScriptBlock, + [string] + $ScriptName, + + [Parameter(Mandatory)] + [ScriptBlockAst] + $ScriptBlockAst, [Parameter(Mandatory)] [String] @@ -39,7 +43,7 @@ Function New-CoverageBreakpointsForScriptBlock { $predicate = { $args[0] -is [CommandBaseAst] } - $scriptCmds = $ScriptBlock.Ast.FindAll($predicate, $true) + $scriptCmds = $ScriptBlockAst.FindAll($predicate, $true) # Create an object that tracks the Ansible path of the file and the breakpoints that have been set in it $info = [PSCustomObject]@{ @@ -68,7 +72,7 @@ Function New-CoverageBreakpointsForScriptBlock { } # Action is explicitly $null as it will slow down the runtime quite dramatically. - $b = $lineCtor.Invoke(@($ScriptBlock.File, $cmd.Extent.StartLineNumber, $cmd.Extent.StartColumnNumber, $null)) + $b = $lineCtor.Invoke(@($ScriptName, $cmd.Extent.StartLineNumber, $cmd.Extent.StartColumnNumber, $null)) $info.Breakpoints.Add($b) } @@ -102,11 +106,16 @@ try { $coveragePathFilter = $PathFilter.Split(":", [StringSplitOptions]::RemoveEmptyEntries) $breakpointInfo = @( foreach ($scriptName in @($ModuleName; $actionParams.PowerShellModules)) { - $scriptInfo = Get-AnsibleScript -Name $scriptName -IncludeScriptBlock + # We don't use -IncludeScriptBlock as the script might be untrusted + # and will run under CLM. While we recreate the ScriptBlock here it + # is only to get the AST that contains the statements and their + # line numbers to create the breakpoint info for. + $scriptInfo = Get-AnsibleScript -Name $scriptName if (Compare-PathFilterPattern -Patterns $coveragePathFilter -Path $scriptInfo.Path) { $covParams = @{ - ScriptBlock = $scriptInfo.ScriptBlock + ScriptName = $scriptInfo.Name + ScriptBlockAst = [ScriptBlock]::Create($scriptInfo.Script).Ast AnsiblePath = $scriptInfo.Path } New-CoverageBreakpointsForScriptBlock @covParams diff --git a/lib/ansible/executor/powershell/module_wrapper.ps1 b/lib/ansible/executor/powershell/module_wrapper.ps1 index b1839c1aa65..253cff29c7d 100644 --- a/lib/ansible/executor/powershell/module_wrapper.ps1 +++ b/lib/ansible/executor/powershell/module_wrapper.ps1 @@ -98,7 +98,9 @@ if ($ForModule) { $ps.Runspace.SessionStateProxy.SetVariable("ErrorActionPreference", "Stop") } else { - # For script files we want to ensure we load it as UTF-8 + # For script files we want to ensure we load it as UTF-8. We don't set this + # for modules as they are loaded from memory whereas a script is loaded + # from disk as part of the script being run than by us. Set-WinPSDefaultFileEncoding }