Skip to content

Commit bb3c8a2

Browse files
authored
Fix an indexing out of bound error in CompleteInput for empty script input (#19501)
1 parent 7144ec7 commit bb3c8a2

4 files changed

Lines changed: 27 additions & 3 deletions

File tree

src/System.Management.Automation/engine/CommandCompletion/CommandCompletion.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static Tuple<Ast, Token[], IScriptPosition> MapStringInputToParsedInput(s
9191
/// <returns></returns>
9292
public static CommandCompletion CompleteInput(string input, int cursorIndex, Hashtable options)
9393
{
94-
if (input == null)
94+
if (input == null || input.Length == 0)
9595
{
9696
return s_emptyCommandCompletion;
9797
}
@@ -124,6 +124,11 @@ public static CommandCompletion CompleteInput(Ast ast, Token[] tokens, IScriptPo
124124
throw PSTraceSource.NewArgumentNullException(nameof(positionOfCursor));
125125
}
126126

127+
if (ast.Extent.Text.Length == 0)
128+
{
129+
return s_emptyCommandCompletion;
130+
}
131+
127132
return CompleteInputImpl(ast, tokens, positionOfCursor, options);
128133
}
129134

@@ -138,7 +143,7 @@ public static CommandCompletion CompleteInput(Ast ast, Token[] tokens, IScriptPo
138143
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "powershell")]
139144
public static CommandCompletion CompleteInput(string input, int cursorIndex, Hashtable options, PowerShell powershell)
140145
{
141-
if (input == null)
146+
if (input == null || input.Length == 0)
142147
{
143148
return s_emptyCommandCompletion;
144149
}
@@ -221,6 +226,11 @@ public static CommandCompletion CompleteInput(Ast ast, Token[] tokens, IScriptPo
221226
throw PSTraceSource.NewArgumentNullException(nameof(powershell));
222227
}
223228

229+
if (ast.Extent.Text.Length == 0)
230+
{
231+
return s_emptyCommandCompletion;
232+
}
233+
224234
// If we are in a debugger stop, let the debugger do the command completion.
225235
var debugger = powershell.Runspace?.Debugger;
226236
if ((debugger != null) && debugger.InBreakpoint)

src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ internal static AstAnalysisContext ExtractAstContext(Ast inputAst, Token[] input
155155
ast => IsCursorWithinOrJustAfterExtent(positionForAstSearch, ast.Extent),
156156
searchNestedScriptBlocks: true).ToList();
157157

158+
if (relatedAsts.Count == 0)
159+
{
160+
relatedAsts.Add(inputAst);
161+
}
162+
158163
// If the last ast is an unnamed block that starts with "param" the cursor is inside a param block.
159164
// To avoid adding special handling to all the completers that look at the last ast, we remove it here because it's not useful for completion.
160165
if (relatedAsts[^1].Extent.Text.StartsWith("param", StringComparison.OrdinalIgnoreCase)

src/System.Management.Automation/engine/InitialSessionState.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4044,6 +4044,7 @@ internal void ImportCmdletsFromAssembly(Assembly assembly, PSModuleInfo module)
40444044
[OutputType([System.Management.Automation.CommandCompletion])]
40454045
Param(
40464046
[Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 0)]
4047+
[AllowEmptyString()]
40474048
[string] $inputScript,
40484049
40494050
[Parameter(ParameterSetName = 'ScriptInputSet', Position = 1)]
@@ -4081,7 +4082,7 @@ internal void ImportCmdletsFromAssembly(Assembly assembly, PSModuleInfo module)
40814082
<#options#> $options)
40824083
}
40834084
}
4084-
";
4085+
";
40854086

40864087
/// <summary>
40874088
/// This is the default function to use for clear-host.

test/powershell/Host/TabCompletion/TabCompletion.Tests.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,14 @@ dir -Recurse `
20502050
param($inputStr, $expected)
20512051
$inputStr | Should -Throw -ErrorId $expected
20522052
}
2053+
2054+
It "Should not throw errors in tab completion with empty input string" {
2055+
{[System.Management.Automation.CommandCompletion]::CompleteInput("", 0, $null)} | Should -Not -Throw
2056+
}
2057+
2058+
It "Should not throw errors in tab completion with empty input ast" {
2059+
{[System.Management.Automation.CommandCompletion]::CompleteInput({}.Ast, @(), {}.Ast.Extent.StartScriptPosition, $null)} | Should -Not -Throw
2060+
}
20532061
}
20542062

20552063
Context "DSC tab completion tests" {

0 commit comments

Comments
 (0)