commandlineparser / commandlineparser/commandline
Parameter name is treated as parameter value
- Lenguaje dominante
- C#
- Estrellas
- 4.8k
- Forks
- 478
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
If I omit parameter value for one parameter name, next parametername is treated as value of the parameter.
Occurred at v2.9.1 from Nuget.
### What I observed
Code:
```
using System;
using CommandLine;
class Options
{
[Option('a', "option1", Required = true)]
public string Option1 { get; set; }
[Option('b', "option2", Required = false)]
public int option2 { get; set; }
}
class Program
{
static int Main(string[] args)
{
return Parser.Default.ParseArguments(args)
.MapResult(
options => RunAndReturnExitCode(options),
_ => -1);
}
static int RunAndReturnExitCode(Options options)
{
Console.WriteLine($"option1={options.Option1}, option2={options.option2}");
return 0;
}
}
```
Command line,
`$command --option1 --option2 5`
gives the result output,
`option1=option2, option2=0`
But expected result is to report error with lacking of required "option1".
### Suggested fix
In the method "CommandLine.Core.TokenPartitioner.PartitionTokensByType", scalarTokens.add(Scalar nem token) shall be occurred only when the following value is confirmed.
```
public static Tuple, IEnumerable, IEnumerable, IEnumerable> PartitionTokensByType(
IEnumerable tokens,
Func> typeLookup)
{
var switchTokens = new List();
var scalarTokens = new List();
var sequenceTokens = new List();
var nonOptionTokens = new List();
var sequences = new Dictionary>();
var count = new Dictionary();
var max = new Dictionary>();
var state = SequenceState.TokenSearch;
var separatorSeen = false;
Token nameToken = null;
foreach (var token in tokens)
{
if (token.IsValueForced())
{
separatorSeen = false;
nonOptionTokens.Add(token);
}
else if (token.IsName())
{
separatorSeen = false;
if (typeLookup(token.Text).MatchJust(out var info))
{
switch (info.TargetType)
{
case TargetType.Switch:
nameToken = null;
switchTokens.Add(token);
state = SequenceState.TokenSearch;
break;
case TargetType.Scalar:
nameToken = token;
// scalarTokens.Add(nameToken); <- don't add here
state = SequenceState.ScalarTokenFound;
break;
case TargetType.Sequence:
nameToken = token;
if (! sequences.ContainsKey(nameToken))
{
sequences[nameToken] = new List();
count[nameToken] = 0;
max[nameToken] = info.MaxItems;
}
state = SequenceState.SequenceTokenFound;
break;
}
}
else
{
nameToken = null;
nonOptionTokens.Add(token);
state = SequenceState.TokenSearch;
}
}
else
{
switch (state)
{
case SequenceState.TokenSearch:
case SequenceState.ScalarTokenFound when nameToken == null:
case SequenceState.SequenceTokenFound when nameToken == null:
separatorSeen = false;
nameToken = null;
nonOptionTokens.Add(token);
state = SequenceState.TokenSearch;
break;
case SequenceState.ScalarTokenFound:
separatorSeen = false;
scalarTokens.Add(nameToken); // add here instead so that scalar name token is valid only when a value is given
nameToken = null;
scalarTokens.Add(token);
state = SequenceState.TokenSearch;
break;
......
```
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Línea de trabajo
Comience en CommandLine.Core.TokenPartitioner.PartitionTokensByType y reproduzca el problema con `--option1 --option2 5` usando el ejemplo de C# proporcionado. Siga el estado ScalarTokenFound y verifique que el nombre de una opción escalar solo se conserve cuando va seguido de un valor. Se considera terminado cuando la opción requerida que falta, option1, se informa como un error en lugar de tratar option2 como su valor.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- csharp
- Área
- cli
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Estancado
- Claridad
- Bien especificado
- Aptitud para principiantes
- 35/100