Deny option (or something that looks like an option) as option argument.
Add TestOptionAsArgument.
diff --git a/parser_private.go b/parser_private.go
index 67a5b02..308f6b8 100644
--- a/parser_private.go
+++ b/parser_private.go
@@ -171,6 +171,10 @@
arg = *argument
} else {
arg = s.pop()
+ if len(arg) > 0 && arg[0] == '-' {
+ msg := fmt.Sprintf("expected argument for flag `%s', got option `%s'", option, arg)
+ return newError(ErrExpectedArgument, msg)
+ }
}
if option.tag.Get("unquote") != "false" {
diff --git a/parser_test.go b/parser_test.go
index ea5006e..8080031 100644
--- a/parser_test.go
+++ b/parser_test.go
@@ -305,3 +305,56 @@
}
}
}
+
+func TestOptionAsArgument(t *testing.T) {
+ var tests = []struct {
+ msg string
+ args []string
+ expectError bool
+ errType ErrorType
+ }{
+ {
+ msg: "short option must not be accepted as argument",
+ args: []string{"--string-slice", "foobar", "--string-slice", "-o"},
+ expectError: true,
+ errType: ErrExpectedArgument,
+ },
+ {
+ msg: "long option must not be accepted as argument",
+ args: []string{"--string-slice", "foobar", "--string-slice", "--other-option"},
+ expectError: true,
+ errType: ErrExpectedArgument,
+ },
+ {
+ msg: "quoted and appended option should be accepted as argument (even if it looks like an option)",
+ args: []string{"--string-slice", "foobar", "--string-slice=\"--other-option\""},
+ },
+ }
+ var opts struct {
+ StringSlice []string `long:"string-slice"`
+ OtherOption bool `long:"other-option" short:"o"`
+ }
+
+ parser := NewParser(&opts, PassDoubleDash)
+
+ for _, test := range tests {
+ _, err := parser.ParseArgs(test.args)
+
+ if test.expectError {
+ if err == nil {
+ t.Fatalf("Expected error")
+ }
+ parseError, ok := err.(*Error)
+ if !ok {
+ t.Fatalf("Expected error of type *flags.Error")
+ }
+ if parseError.Type != test.errType {
+ t.Fatalf("Expected error type %s but got %s", test.errType, parseError.Type)
+ }
+ } else {
+ if err != nil {
+ t.Fatalf("Expected no error but got: %v", err)
+ }
+ }
+ }
+}