From 9934507d74c97bccb753b04873eb74652600b6ff Mon Sep 17 00:00:00 2001
From: Ed Santiago <santiago@redhat.com>
Date: Tue, 26 Feb 2019 12:28:35 -0700
Subject: [PATCH] Command-line input validation: reject unused args

Several podman commands accept no subcommands. Some
of those were not actually checking, though, which
could lead to user confusion. Added validation where
missing; and, refactored to minimize duplication.

(Side note: I decided against using cobra.NoArgs
because its error message, "unknown command",
misleadingly implies that there are known ones).

Also added validation to varlink

Signed-off-by: Ed Santiago <santiago@redhat.com>
---
 cmd/podman/common.go           | 8 ++++++++
 cmd/podman/containers_prune.go | 1 +
 cmd/podman/images_prune.go     | 1 +
 cmd/podman/info.go             | 1 +
 cmd/podman/pod_create.go       | 4 +---
 cmd/podman/pod_ps.go           | 5 +----
 cmd/podman/ps.go               | 5 +----
 cmd/podman/refresh.go          | 5 +----
 cmd/podman/system_renumber.go  | 1 +
 cmd/podman/varlink.go          | 3 +++
 cmd/podman/version.go          | 1 +
 cmd/podman/volume_ls.go        | 5 +----
 cmd/podman/volume_prune.go     | 1 +
 13 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index e297f39219..1fb06cf910 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -59,6 +59,14 @@ func checkAllAndLatest(c *cobra.Command, args []string, ignoreArgLen bool) error
 	return nil
 }
 
+// noSubArgs checks that there are no further positional parameters
+func noSubArgs(c *cobra.Command, args []string) error {
+	if len(args) > 0 {
+		return errors.Errorf("`%s` takes no arguments", c.CommandPath())
+	}
+	return nil
+}
+
 // getAllOrLatestContainers tries to return the correct list of containers
 // depending if --all, --latest or <container-id> is used.
 // It requires the Context (c) and the Runtime (runtime). As different
diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go
index 6e49604293..0d0e753325 100644
--- a/cmd/podman/containers_prune.go
+++ b/cmd/podman/containers_prune.go
@@ -21,6 +21,7 @@ var (
 `
 	_pruneContainersCommand = &cobra.Command{
 		Use:   "prune",
+		Args:  noSubArgs,
 		Short: "Remove all stopped containers",
 		Long:  pruneContainersDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go
index 79dcd097c8..427374f68a 100644
--- a/cmd/podman/images_prune.go
+++ b/cmd/podman/images_prune.go
@@ -18,6 +18,7 @@ var (
 `
 	_pruneImagesCommand = &cobra.Command{
 		Use:   "prune",
+		Args:  noSubArgs,
 		Short: "Remove unused images",
 		Long:  pruneImagesDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/info.go b/cmd/podman/info.go
index a1473dac9c..e87f4e1515 100644
--- a/cmd/podman/info.go
+++ b/cmd/podman/info.go
@@ -19,6 +19,7 @@ var (
 	infoDescription = "Display podman system information"
 	_infoCommand    = &cobra.Command{
 		Use:   "info",
+		Args:  noSubArgs,
 		Long:  infoDescription,
 		Short: `Display information pertaining to the host, current storage stats, and build of podman. Useful for the user and when reporting issues.`,
 		RunE: func(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go
index f1bbecb84c..43c211b2cf 100644
--- a/cmd/podman/pod_create.go
+++ b/cmd/podman/pod_create.go
@@ -24,6 +24,7 @@ var (
 
 	_podCreateCommand = &cobra.Command{
 		Use:   "create",
+		Args:  noSubArgs,
 		Short: "Create a new empty pod",
 		Long:  podCreateDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -59,9 +60,6 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error {
 		podIdFile *os.File
 	)
 
-	if len(c.InputArgs) > 0 {
-		return errors.New("podman pod create does not accept any arguments")
-	}
 	runtime, err := adapter.GetRuntime(&c.PodmanCommand)
 	if err != nil {
 		return errors.Wrapf(err, "error creating libpod runtime")
diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go
index 70e0776510..8e48740e6f 100644
--- a/cmd/podman/pod_ps.go
+++ b/cmd/podman/pod_ps.go
@@ -121,6 +121,7 @@ var (
 	_podPsCommand    = &cobra.Command{
 		Use:     "ps",
 		Aliases: []string{"ls", "list"},
+		Args:    noSubArgs,
 		Short:   "List pods",
 		Long:    podPsDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -160,10 +161,6 @@ func podPsCmd(c *cliconfig.PodPsValues) error {
 	}
 	defer runtime.Shutdown(false)
 
-	if len(c.InputArgs) > 0 {
-		return errors.Errorf("too many arguments, ps takes no arguments")
-	}
-
 	opts := podPsOptions{
 		NoTrunc:            c.NoTrunc,
 		Quiet:              c.Quiet,
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index 3bc4f0b085..d6edcabcbf 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -159,6 +159,7 @@ var (
 	psDescription = "Prints out information about the containers"
 	_psCommand    = &cobra.Command{
 		Use:   "ps",
+		Args:  noSubArgs,
 		Short: "List containers",
 		Long:  psDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -215,10 +216,6 @@ func psCmd(c *cliconfig.PsValues) error {
 
 	defer runtime.Shutdown(false)
 
-	if len(c.InputArgs) > 0 {
-		return errors.Errorf("too many arguments, ps takes no arguments")
-	}
-
 	opts := shared.PsOptions{
 		All:       c.All,
 		Format:    c.Format,
diff --git a/cmd/podman/refresh.go b/cmd/podman/refresh.go
index 641748452f..2eb3d25a83 100644
--- a/cmd/podman/refresh.go
+++ b/cmd/podman/refresh.go
@@ -15,6 +15,7 @@ var (
 	refreshDescription = "The refresh command resets the state of all containers to handle database changes after a Podman upgrade. All running containers will be restarted."
 	_refreshCommand    = &cobra.Command{
 		Use:   "refresh",
+		Args:  noSubArgs,
 		Short: "Refresh container state",
 		Long:  refreshDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -31,10 +32,6 @@ func init() {
 }
 
 func refreshCmd(c *cliconfig.RefreshValues) error {
-	if len(c.InputArgs) > 0 {
-		return errors.Errorf("refresh does not accept any arguments")
-	}
-
 	runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
 	if err != nil {
 		return errors.Wrapf(err, "error creating libpod runtime")
diff --git a/cmd/podman/system_renumber.go b/cmd/podman/system_renumber.go
index c8ce628b13..31137b9f65 100644
--- a/cmd/podman/system_renumber.go
+++ b/cmd/podman/system_renumber.go
@@ -18,6 +18,7 @@ var (
 
 	_renumberCommand = &cobra.Command{
 		Use:   "renumber",
+		Args:  noSubArgs,
 		Short: "Migrate lock numbers",
 		Long:  renumberDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go
index f19d03885a..5cc79ef964 100644
--- a/cmd/podman/varlink.go
+++ b/cmd/podman/varlink.go
@@ -49,6 +49,9 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error {
 	if len(args) < 1 {
 		return errors.Errorf("you must provide a varlink URI")
 	}
+	if len(args) > 1 {
+		return errors.Errorf("too many arguments. Requires exactly 1")
+	}
 	timeout := time.Duration(c.Timeout) * time.Millisecond
 
 	// Create a single runtime for varlink
diff --git a/cmd/podman/version.go b/cmd/podman/version.go
index c65ba94f95..b3615ce23a 100644
--- a/cmd/podman/version.go
+++ b/cmd/podman/version.go
@@ -17,6 +17,7 @@ var (
 	versionCommand  cliconfig.VersionValues
 	_versionCommand = &cobra.Command{
 		Use:   "version",
+		Args:  noSubArgs,
 		Short: "Display the Podman Version Information",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			versionCommand.InputArgs = args
diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go
index 5adfc1e91f..6855f38e04 100644
--- a/cmd/podman/volume_ls.go
+++ b/cmd/podman/volume_ls.go
@@ -49,6 +49,7 @@ and the output format can be changed to JSON or a user specified Go template.
 	_volumeLsCommand = &cobra.Command{
 		Use:     "ls",
 		Aliases: []string{"list"},
+		Args:    noSubArgs,
 		Short:   "List volumes",
 		Long:    volumeLsDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {
@@ -76,10 +77,6 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error {
 	}
 	defer runtime.Shutdown(false)
 
-	if len(c.InputArgs) > 0 {
-		return errors.Errorf("too many arguments, ls takes no arguments")
-	}
-
 	opts := volumeLsOptions{
 		Quiet: c.Quiet,
 	}
diff --git a/cmd/podman/volume_prune.go b/cmd/podman/volume_prune.go
index 1f7931aa43..370f072eb2 100644
--- a/cmd/podman/volume_prune.go
+++ b/cmd/podman/volume_prune.go
@@ -24,6 +24,7 @@ using force.
 `
 	_volumePruneCommand = &cobra.Command{
 		Use:   "prune",
+		Args:  noSubArgs,
 		Short: "Remove all unused volumes",
 		Long:  volumePruneDescription,
 		RunE: func(cmd *cobra.Command, args []string) error {