From 2e81334206442a1853cdc5a3f626e8ee0b113494 Mon Sep 17 00:00:00 2001 From: Alex Flint Date: Tue, 20 Apr 2021 19:09:47 -0700 Subject: [PATCH] fix case where an environment variable containing an empty string is parsed into a slice or map --- parse.go | 18 +++++++++++------- parse_test.go | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/parse.go b/parse.go index 94c0a89..13e8195 100644 --- a/parse.go +++ b/parse.go @@ -441,13 +441,17 @@ func (p *Parser) captureEnvVars(specs []*spec, wasPresent map[*spec]bool) error if spec.cardinality == multiple { // expect a CSV string in an environment // variable in the case of multiple values - values, err := csv.NewReader(strings.NewReader(value)).Read() - if err != nil { - return fmt.Errorf( - "error reading a CSV string from environment variable %s with multiple values: %v", - spec.env, - err, - ) + var values []string + var err error + if len(strings.TrimSpace(value)) > 0 { + values, err = csv.NewReader(strings.NewReader(value)).Read() + if err != nil { + return fmt.Errorf( + "error reading a CSV string from environment variable %s with multiple values: %v", + spec.env, + err, + ) + } } if err = setSliceOrMap(p.val(spec.dest), values, !spec.separate); err != nil { return fmt.Errorf( diff --git a/parse_test.go b/parse_test.go index 09fb508..695b1d8 100644 --- a/parse_test.go +++ b/parse_test.go @@ -721,6 +721,15 @@ func TestEnvironmentVariableSliceArgumentString(t *testing.T) { assert.Equal(t, []string{"bar", "baz, qux"}, args.Foo) } +func TestEnvironmentVariableSliceEmpty(t *testing.T) { + var args struct { + Foo []string `arg:"env"` + } + _, err := parseWithEnv("", []string{`FOO=`}, &args) + require.NoError(t, err) + assert.Len(t, args.Foo, 0) +} + func TestEnvironmentVariableSliceArgumentInteger(t *testing.T) { var args struct { Foo []int `arg:"env"` @@ -775,6 +784,15 @@ func TestEnvironmentVariableMap(t *testing.T) { assert.Equal(t, "ninetynine", args.Foo[99]) } +func TestEnvironmentVariableEmptyMap(t *testing.T) { + var args struct { + Foo map[int]string `arg:"env"` + } + _, err := parseWithEnv("", []string{`FOO=`}, &args) + require.NoError(t, err) + assert.Len(t, args.Foo, 0) +} + func TestEnvironmentVariableIgnored(t *testing.T) { var args struct { Foo string `arg:"env"`