commandlineparser / commandlineparser/commandline

Parameter name is treated as parameter value

Abierto
#857 4 comentarios 1 reacción 0 asignados Ver en GitHub
bug help wanted
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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.