From 28306a49c42792fbdd67b35be984ac187c42852d Mon Sep 17 00:00:00 2001
From: Matt Bell <mappum@gmail.com>
Date: Wed, 12 Nov 2014 23:38:14 -0800
Subject: [PATCH] commands/cli,http: Properly preserve argument value count
 when checking argument validity

---
 commands/cli/parse.go  | 21 +++++++++------------
 commands/http/parse.go | 23 +++++++++++------------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/commands/cli/parse.go b/commands/cli/parse.go
index 3beb0e600..db1d13403 100644
--- a/commands/cli/parse.go
+++ b/commands/cli/parse.go
@@ -109,8 +109,6 @@ func parseOptions(input []string) (map[string]interface{}, []string, error) {
 }
 
 func parseArgs(stringArgs []string, cmd *cmds.Command) ([]interface{}, error) {
-	args := make([]interface{}, 0)
-
 	// count required argument definitions
 	lenRequired := 0
 	for _, argDef := range cmd.Arguments {
@@ -119,6 +117,8 @@ func parseArgs(stringArgs []string, cmd *cmds.Command) ([]interface{}, error) {
 		}
 	}
 
+	args := make([]interface{}, len(stringArgs))
+
 	valueIndex := 0 // the index of the current stringArgs value
 	for _, argDef := range cmd.Arguments {
 		// skip optional argument definitions if there aren't sufficient remaining values
@@ -134,39 +134,36 @@ func parseArgs(stringArgs []string, cmd *cmds.Command) ([]interface{}, error) {
 
 		if argDef.Variadic {
 			for _, arg := range stringArgs[valueIndex:] {
-				var err error
-				args, err = appendArg(args, argDef, arg)
+				value, err := argValue(argDef, arg)
 				if err != nil {
 					return nil, err
 				}
+				args[valueIndex] = value
 				valueIndex++
 			}
 		} else {
 			var err error
-			args, err = appendArg(args, argDef, stringArgs[valueIndex])
+			value, err := argValue(argDef, stringArgs[valueIndex])
 			if err != nil {
 				return nil, err
 			}
+			args[valueIndex] = value
 			valueIndex++
 		}
 	}
 
-	if len(stringArgs)-valueIndex > 0 {
-		args = append(args, make([]interface{}, len(stringArgs)-valueIndex))
-	}
-
 	return args, nil
 }
 
-func appendArg(args []interface{}, argDef cmds.Argument, value string) ([]interface{}, error) {
+func argValue(argDef cmds.Argument, value string) (interface{}, error) {
 	if argDef.Type == cmds.ArgString {
-		return append(args, value), nil
+		return value, nil
 
 	} else {
 		in, err := os.Open(value) // FIXME(btc) must close file. fix before merge
 		if err != nil {
 			return nil, err
 		}
-		return append(args, in), nil
+		return in, nil
 	}
 }
diff --git a/commands/http/parse.go b/commands/http/parse.go
index 6c897ee5e..a59bb3b78 100644
--- a/commands/http/parse.go
+++ b/commands/http/parse.go
@@ -39,8 +39,6 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
 	opts, stringArgs2 := parseOptions(r)
 	stringArgs = append(stringArgs, stringArgs2...)
 
-	args := make([]interface{}, 0)
-
 	// count required argument definitions
 	numRequired := 0
 	for _, argDef := range cmd.Arguments {
@@ -52,13 +50,16 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
 	// count the number of provided argument values
 	valCount := len(stringArgs)
 	// TODO: add total number of parts in request body (instead of just 1 if body is present)
-	if r.Body != nil {
+	if r.Body != nil && r.ContentLength != 0 {
 		valCount += 1
 	}
 
+	args := make([]interface{}, valCount)
+
+	valIndex := 0
 	for _, argDef := range cmd.Arguments {
 		// skip optional argument definitions if there aren't sufficient remaining values
-		if valCount <= numRequired && !argDef.Required {
+		if valCount-valIndex <= numRequired && !argDef.Required {
 			continue
 		} else if argDef.Required {
 			numRequired--
@@ -67,14 +68,15 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
 		if argDef.Type == cmds.ArgString {
 			if argDef.Variadic {
 				for _, s := range stringArgs {
-					args = append(args, s)
+					args[valIndex] = s
+					valIndex++
 				}
 				valCount -= len(stringArgs)
 
 			} else if len(stringArgs) > 0 {
-				args = append(args, stringArgs[0])
+				args[valIndex] = stringArgs[0]
 				stringArgs = stringArgs[1:]
-				valCount--
+				valIndex++
 
 			} else {
 				break
@@ -82,14 +84,11 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
 
 		} else {
 			// TODO: create multipart streams for file args
-			args = append(args, r.Body)
+			args[valIndex] = r.Body
+			valIndex++
 		}
 	}
 
-	if valCount-1 > 0 {
-		args = append(args, make([]interface{}, valCount-1))
-	}
-
 	optDefs, err := root.GetOptions(path)
 	if err != nil {
 		return nil, err
-- 
GitLab