validateFlags command line options to make sure the user entered a value

When a user enters a CLI with a StringFlags or StringSliceFlags and does not add
a value the CLI mistakently takes the next option and uses it as a value.

This usually ends up with an error like not enough options or others.  Some times
it could also succeed, with weird results.  This patch looks for any values that
begin with a "-" and return an error.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2017-09-28 18:44:48 +00:00
parent 3e2ad8f10a
commit 04e96d05fc
20 changed files with 90 additions and 0 deletions

View file

@ -2,6 +2,8 @@ package main
import (
"os"
"reflect"
"regexp"
"strings"
is "github.com/containers/image/storage"
@ -100,3 +102,34 @@ func splitCamelCase(src string) string {
entries := camelcase.Split(src)
return strings.Join(entries, " ")
}
// validateFlags searches for StringFlags or StringSlice flags that never had
// a value set. This commonly occurs when the CLI mistakenly takes the next
// option and uses it as a value.
func validateFlags(c *cli.Context, flags []cli.Flag) error {
for _, flag := range flags {
switch reflect.TypeOf(flag).String() {
case "cli.StringSliceFlag":
{
f := flag.(cli.StringSliceFlag)
name := strings.Split(f.Name, ",")
val := c.StringSlice(name[0])
for _, v := range val {
if ok, _ := regexp.MatchString("^-.+", v); ok {
return errors.Errorf("option --%s requires a value", name[0])
}
}
}
case "cli.StringFlag":
{
f := flag.(cli.StringFlag)
name := strings.Split(f.Name, ",")
val := c.String(name[0])
if ok, _ := regexp.MatchString("^-.+", val); ok {
return errors.Errorf("option --%s requires a value", name[0])
}
}
}
}
return nil
}

View file

@ -77,6 +77,9 @@ func diffCmd(c *cli.Context) error {
if len(c.Args()) != 1 {
return errors.Errorf("container, layer, or image name must be specified: kpod diff [options [...]] ID-NAME")
}
if err := validateFlags(c, diffFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "could not get config")

View file

@ -48,6 +48,9 @@ func exportCmd(c *cli.Context) error {
return errors.Errorf("too many arguments given, need 1 at most.")
}
container := args[0]
if err := validateFlags(c, exportFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {

View file

@ -85,6 +85,9 @@ var (
)
func historyCmd(c *cli.Context) error {
if err := validateFlags(c, historyFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "Could not get config")

View file

@ -52,6 +52,9 @@ var (
)
func imagesCmd(c *cli.Context) error {
if err := validateFlags(c, imagesFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "Could not get config")

View file

@ -36,6 +36,9 @@ var (
)
func infoCmd(c *cli.Context) error {
if err := validateFlags(c, infoFlags); err != nil {
return err
}
info := map[string]interface{}{}
infoGivers := []infoGiverFunc{

View file

@ -49,6 +49,9 @@ func inspectCmd(c *cli.Context) error {
if len(args) > 1 {
return errors.Errorf("too many arguments specified")
}
if err := validateFlags(c, inspectFlags); err != nil {
return err
}
itemType := c.String("type")
size := c.Bool("size")

View file

@ -35,6 +35,9 @@ func killCmd(c *cli.Context) error {
if len(args) == 0 {
return errors.Errorf("specify one or more containers to kill")
}
if err := validateFlags(c, killFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "could not get config")

View file

@ -45,6 +45,9 @@ func loadCmd(c *cli.Context) error {
if len(args) > 1 {
return errors.New("too many arguments. Requires exactly 1")
}
if err := validateFlags(c, loadFlags); err != nil {
return err
}
runtime, err := getRuntime(c)
if err != nil {

View file

@ -46,6 +46,9 @@ func logsCmd(c *cli.Context) error {
if len(args) != 1 {
return errors.Errorf("'kpod logs' requires exactly one container name/ID")
}
if err := validateFlags(c, logsFlags); err != nil {
return err
}
container := c.Args().First()
var opts libkpod.LogOptions
opts.Details = c.Bool("details")

View file

@ -64,6 +64,9 @@ func mountCmd(c *cli.Context) error {
if len(args) > 1 {
return errors.Errorf("too many arguments specified")
}
if err := validateFlags(c, mountFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "Could not get config")

View file

@ -143,6 +143,9 @@ var (
)
func psCmd(c *cli.Context) error {
if err := validateFlags(c, psFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "could not get config")

View file

@ -129,6 +129,9 @@ func pullCmd(c *cli.Context) error {
logrus.Errorf("too many arguments. Requires exactly 1")
return nil
}
if err := validateFlags(c, pullFlags); err != nil {
return err
}
image := args[0]
srcRef, err := alltransports.ParseImageName(image)
if err != nil {

View file

@ -68,6 +68,9 @@ func pushCmd(c *cli.Context) error {
if len(args) < 2 {
return errors.New("kpod push requires exactly 2 arguments")
}
if err := validateFlags(c, pushFlags); err != nil {
return err
}
srcName := c.Args().Get(0)
destName := c.Args().Get(1)

View file

@ -23,6 +23,9 @@ func renameCmd(c *cli.Context) error {
if len(c.Args()) != 2 {
return errors.Errorf("Rename requires a src container name/ID and a dest container name")
}
if err := validateFlags(c, renameFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {

View file

@ -33,6 +33,9 @@ func rmCmd(c *cli.Context) error {
if len(args) == 0 {
return errors.Errorf("specify one or more containers to remove")
}
if err := validateFlags(c, rmFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {

View file

@ -28,6 +28,9 @@ var (
)
func rmiCmd(c *cli.Context) error {
if err := validateFlags(c, rmiFlags); err != nil {
return err
}
force := false
if c.IsSet("force") {

View file

@ -47,6 +47,9 @@ func saveCmd(c *cli.Context) error {
if len(args) == 0 {
return errors.Errorf("need at least 1 argument")
}
if err := validateFlags(c, saveFlags); err != nil {
return err
}
runtime, err := getRuntime(c)
if err != nil {

View file

@ -62,6 +62,9 @@ var (
)
func statsCmd(c *cli.Context) error {
if err := validateFlags(c, statsFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {
return errors.Wrapf(err, "could not read config")

View file

@ -42,6 +42,9 @@ func stopCmd(c *cli.Context) error {
if len(args) < 1 {
return errors.Errorf("you must provide at least one container name or id")
}
if err := validateFlags(c, stopFlags); err != nil {
return err
}
config, err := getConfig(c)
if err != nil {