dotnet / dotnet/command-line-api

Completion crashes when using `=` syntax for options

Aperta
#2,279 12 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
C#
Stelle
3.7k
Fork
428
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

System.CommandLine version: 2.0.0-beta4.22272.1

There is a mismatch between how `=` is handled between splitting up the tokens and processing words for completion, which results in a crash.

```C#
using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Parsing;

RootCommand root = new();
root.AddOption(new Option("--test").AddCompletions("asdf"));

CommandLineBuilder builder = new(root);
builder.UseDefaults();
return await builder.Build().InvokeAsync(args);
```

Attempting tab completion on `CompletionCrashRepro --test=asd` results in a crash:

```
> System.Linq.dll!System.Linq.ThrowHelper.ThrowNoMatchException() Line 27 C#
System.Linq.dll!System.Linq.Enumerable.Last(System.Collections.Generic.IEnumerable source, System.Func predicate) Line 30 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParseResult.SymbolToComplete.__WillAcceptAnArgument|42_1(System.CommandLine.Parsing.ParseResult parseResult, int? position, System.CommandLine.Parsing.OptionResult optionResult) Line 305 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParseResult.SymbolToComplete.__AllSymbolResultsForCompletion|0() Line 271 C#
System.Linq.dll!System.Collections.Generic.LargeArrayBuilder.AddRange(System.Collections.Generic.IEnumerable items) Line 116 C#
System.Linq.dll!System.Collections.Generic.EnumerableHelpers.ToArray(System.Collections.Generic.IEnumerable source) Line 85 C#
System.Linq.dll!System.Linq.Enumerable.ToArray(System.Collections.Generic.IEnumerable source) Line 17 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParseResult.SymbolToComplete(int? position) Line 255 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParseResult.GetCompletions(int? position) Line 219 C#
System.CommandLine.dll!System.CommandLine.Invocation.SuggestDirectiveResult.Apply(System.CommandLine.Invocation.InvocationContext context) Line 25 C#
System.CommandLine.dll!System.CommandLine.Invocation.InvocationPipeline.GetExitCode(System.CommandLine.Invocation.InvocationContext context) Line 98 C#
System.CommandLine.dll!System.CommandLine.Invocation.InvocationPipeline.InvokeAsync.__FullInvocationChainAsync|2_0(System.CommandLine.Invocation.InvocationContext context) Line 38 C#
System.CommandLine.dll!System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(System.CommandLine.IConsole console) Line 30 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParseResultExtensions.InvokeAsync(System.CommandLine.Parsing.ParseResult parseResult, System.CommandLine.IConsole console) Line 27 C#
System.CommandLine.dll!System.CommandLine.Parsing.ParserExtensions.InvokeAsync(System.CommandLine.Parsing.Parser parser, string[] args, System.CommandLine.IConsole console) Line 54 C#
CompletionCrashRepro.dll!Program.$(string[] args) Line 15 C#
CompletionCrashRepro.dll!Program.(string[] args) Unknown
```

This same crash does _not_ occur if a space is used instead of `=`: `CompletionCrashRepro --test asd`, and the completion works as expected.

(Note: I found the easiest way to actually reproduce this was by running this with the arguments of: `[suggest:30] "CompletionCrashRepro --test=asd"` rather than actually doing tab completion.)

The reason for this is that `ParseResult.WillAcceptAnArgument` has this line:

```C#
var tokenToComplete = parseResult.Tokens.Last(t => t.Value == textCompletionContext.WordToComplete);
```

However, the `=` is stripped out in `parseResult.Tokens` (`["--test", "asd"]`), but not in `textCompletionContext.WordToComplete` (`"--test=asd"`). This results in `.Last(...)` finding no matches, which crashes.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da ParseResult.WillAcceptAnArgument, in particolare dalla ricerca dei token che confronta parseResult.Tokens con textCompletionContext.WordToComplete. Riproduci il problema tramite [suggest:30] con `CompletionCrashRepro --test=asd`, quindi verifica che il completamento non vada più in crash con la sintassi `=` e che restituisca comunque il completamento previsto, come avviene con uno spazio.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
csharp
Ambito
cli
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
38/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.