AvoidReservedCharInCmdlet intermittently throws NullReferenceException from CommandInfo.ResolveParameter

Abierto
#27,842 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
45/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Tranquilo
Stack tecnológico
csharp, powershell
Área
cli, testing-qa

Línea de trabajo

Comienza ejecutando el bucle repro.ps1 proporcionado con Invoke-ScriptAnalyzer y compara las sesiones correctas y fallidas. Sigue la ruta indicada desde AvoidReservedCharInCmdlet y Helper.GetExportedFunction hasta CommandInfo.ResolveParameter, incluidos los llamados concurrentes a las reglas descritos en el informe. Se considera completado cuando el análisis termina sin una excepción y devuelve los diagnósticos del archivo.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Needs-Triage WG-Engine
Prerequisites
Steps to reproduce

Invoke-ScriptAnalyzer intermittently fails with a NullReferenceException when analysing a file that both defines a function and calls Export-ModuleMember. The exception surfaces in AvoidReservedCharInCmdlet, by way of Helper.GetExportedFunction calling CommandInfo.ResolveParameter, and reproduces on the current release in 14/19 of 100 fresh sessions against a four-line file. Under -ErrorAction Stop it terminates the call; under the default preference it can discard the file's diagnostics and still exit zero.

Related: PowerShell/PSScriptAnalyzer#1538 (closed without a reproducer; identical stack), PowerShell/PSScriptAnalyzer#1708 (open; same CommandInfo root, different rule), PowerShell/PSScriptAnalyzer#1351 (open; transient RULE_ERROR, rule unidentified).

Steps to reproduce

  • Requires the PSScriptAnalyzer module ('Install-Module PSScriptAnalyzer').
  • Analysing a file that both defines a function and calls Export-ModuleMember intermittently fails with a NullReferenceException thrown from System.Management.Automation.CommandInfo.ResolveParameter.
  • Neither element on its own reproduces it.

This writes repro.ps1 into the current directory and analyses it there.

# Four lines are enough; nothing else in the file matters.
@'
function Get-Thing {
    return 1
}
Export-ModuleMember -Function Get-Thing
'@ | Set-Content ./repro.ps1

# One analysis per fresh session: the fault surfaces far more readily on the
# first invocation in a process than on later ones.
$threw = 0
1..100 | ForEach-Object {
    $out = pwsh -NoProfile -Command {
        Import-Module PSScriptAnalyzer -ErrorAction Stop
        $ErrorActionPreference = 'Stop'
        try { $null = @(Invoke-ScriptAnalyzer -Path ./repro.ps1); 'OK' } catch { 'THREW' }
    }
    if ($out -match 'THREW') { $threw++ }
}
"threw $threw / 100"

Observations

One hundred fresh sessions per row, on 1.25.0 except the last:

Input or option Threw
The four-line file above 14 / 100; 19 / 100
Function only, no Export-ModuleMember 0 / 100
Export-ModuleMember only, no function 0 / 100
-ExcludeRule PSReservedCmdletChar 0 / 100
-ExcludeRule PSProvideCommentHelp 0 / 100
-Severity Warning 0 / 100
The same file on 1.24.0 11 / 100; 13 / 100
  • The extension is irrelevant: .ps1 and .psm1 reproduce alike, in any directory. Get-Thing contains no reserved character, so the rule reports nothing on this file even on a successful run.
  • Under $ErrorActionPreference = 'Stop' the exception terminates the call, rather than being reported as a non-terminating error.
  • Under the default preference the run continues and the diagnostic can be lost silently.
  • An error-free run returns one finding, PSProvideCommentHelp.
  • The rate is not stable between measurement runs on identical input, which seems consistent with a race condition.
  • The stack names AvoidReservedCharInCmdlet, yet excluding PSProvideCommentHelp also stops it. Both rules reach Helper.GetExportedFunction, so a second concurrent caller appears to be required rather than the throwing rule alone.
  • -Severity Warning masks it because that filter suppresses rule selection rather than filtering diagnostics, so PSProvideCommentHelp never runs. See PowerShell/PSScriptAnalyzer#2156.
Expected behavior
Analysis completes and returns the file's diagnostics. No error is written.
Actual behavior
On a failing run, `Invoke-ScriptAnalyzer` writes:


Invoke-ScriptAnalyzer: Object reference not set to an instance of an object.


- Under `$ErrorActionPreference = 'Stop'` the exception terminates the call.
- Under the default preference the run continues and the diagnostic can be lost silently: an error-free run returns one finding, `PSProvideCommentHelp`.
- The rate is not stable across measurement runs on identical input, consistent with a
race condition.
- Repeated 100-session runs gave 14 and 19 on PSScriptAnalyzer 1.25.0, with 11 and 13 on
1.24.0.
- Excluding either `PSReservedCmdletChar` or `PSProvideCommentHelp` gives 0/100;
both rules reach `Helper.GetExportedFunction`, so a second concurrent caller appears to
be required rather than the throwing rule alone.
Error details
**Error details** — `Get-Error`, verbatim, paths sanitised:


Exception             :
Type       : System.NullReferenceException
TargetSite :
Name          : ResolveParameter
DeclaringType : [System.Management.Automation.CommandInfo]
MemberType    : Method
Module        : System.Management.Automation.dll
Message    : Object reference not set to an instance of an object.
Source     : System.Management.Automation
HResult    : -2147467261
StackTrace :
at System.Management.Automation.CommandInfo.ResolveParameter(String name)
at Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper.GetExportedFunction(Ast ast)
at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.AvoidReservedCharInCmdlet.AnalyzeScript(Ast ast, String fileName)+MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer.<>c__DisplayClass84_1.<AnalyzeSyntaxTree>b__2()
TargetObject          : /path/to/repro.ps1
CategoryInfo          : InvalidOperation: (/path/to/repro.ps1:String) [Invoke-ScriptAnalyzer], NullReferenceException
FullyQualifiedErrorId : RULE_ERROR,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand
InvocationInfo        :
MyCommand        : Invoke-ScriptAnalyzer
ScriptLineNumber : 3
OffsetInLine     : 15
InvocationName   : Invoke-ScriptAnalyzer
CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 3
Environment data
> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.6.4
PSEdition                      Core
GitCommitId                    7.6.4
OS                             Debian GNU/Linux 13 (trixie)
Platform                       Unix

- `PSScriptAnalyzer` 1.24.0 installed
- 1.25.0 (current PSGallery release) tested via `Save-Module` and an explicit manifest import.
- Both versions affected.
- Not tested on Windows or macOS.
Visuals

No response

Lenguaje dominante
C#
Estrellas
55.5k
Forks
8.5k
Merge medio
1 d 11 h
PR fusionados (30 d)
86

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de PowerShell/PowerShell

Todos los issues de PowerShell/PowerShell

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.