Browse Source

refactor: remove the exception filter that no exception can reach

The catch for an UnauthorizedAccessException of Get-ChildItem2 had an exception filter that passes on what a later command raises. A bounded mutation that removed the filter was not detected: PowerShell wraps the exception of a throw, so a cmdlet never sees the type that was thrown, and no later command can raise a raw UnauthorizedAccessException through a Write call. The filter and the test style that was meant to reach it are removed instead of leaving a branch that nothing can enter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/118/head
Raimund Andree 2 days ago
parent
commit
7aa8315ce1
  1. 2
      NTFSSecurity/ItemCmdlets/GetChildItem2.cs
  2. 15
      Tests/PipelineControl.Tests.ps1

2
NTFSSecurity/ItemCmdlets/GetChildItem2.cs

@ -263,7 +263,7 @@ namespace NTFSSecurity
}
}
}
catch (UnauthorizedAccessException ex) when (!IsFromLaterCommand(ex))
catch (UnauthorizedAccessException ex)
{
WriteError(new ErrorRecord(ex, "DirUnauthorizedAccessError", ErrorCategory.PermissionDenied, di.FullName));
}

15
Tests/PipelineControl.Tests.ps1

@ -43,12 +43,12 @@ BeforeDiscovery {
@{ Name = $name }
}
$failureCases = foreach ($name in $names) {
foreach ($style in 'throw', 'throw UnauthorizedAccessException', 'Write-Error -ErrorAction Stop') {
foreach ($style in 'throw', 'Write-Error -ErrorAction Stop') {
@{ Name = $name; Style = $style }
}
}
$auditFailureCases = foreach ($name in $auditNames) {
foreach ($style in 'throw', 'throw UnauthorizedAccessException', 'Write-Error -ErrorAction Stop') {
foreach ($style in 'throw', 'Write-Error -ErrorAction Stop') {
@{ Name = $name; Style = $style }
}
}
@ -353,8 +353,8 @@ BeforeAll {
}
# A later command that fails with a terminating error ends the pipeline for the commands before it. The error is the
# caller's: the cmdlet must neither report it as an error of an item nor go on with the next item. The second style
# raises the type that some catch of the cmdlets handles on its own, for a folder that cannot be read.
# caller's: the cmdlet must neither report it as an error of an item nor go on with the next item. PowerShell wraps
# the exception of a throw, so the cmdlet never sees the type that was thrown.
function Assert-DownstreamFailure {
param ([string] $Name, [string] $Style)
@ -366,11 +366,8 @@ BeforeAll {
try {
& $case.Run $context | ForEach-Object -Process {
$emitted++
switch ($Style) {
'throw' { throw 'Downstream failure' }
'throw UnauthorizedAccessException' { throw [System.UnauthorizedAccessException]::new('Downstream failure') }
default { Write-Error -Message 'Downstream failure' -ErrorAction Stop }
}
if ($Style -eq 'throw') { throw 'Downstream failure' }
Write-Error -Message 'Downstream failure' -ErrorAction Stop
}
}
catch {

Loading…
Cancel
Save