diff options
author | Constantin Konstantinidis <constantinkonstantinidis@gmail.com> | 2019-12-25 17:24:07 +0100 |
---|---|---|
committer | Emmanuel Odeke <emm.odeke@gmail.com> | 2020-02-26 23:27:55 +0000 |
commit | 12cd55c062d6062a64076cb37f12ab7646df1be7 (patch) | |
tree | d6cf6422d1dcdd06c5ccf5cf1d9875b0ed73ea69 /src/io | |
parent | 8bdd24df6afa746cede600351feb2aa4395a63ea (diff) | |
download | go-12cd55c062d6062a64076cb37f12ab7646df1be7.tar.gz go-12cd55c062d6062a64076cb37f12ab7646df1be7.zip |
io/ioutil: reject path separators in TempDir, TempFile pattern
Fixes #33920
Change-Id: I2351a1caa80c086ff5a8e02aad70d996be7aac35
Reviewed-on: https://go-review.googlesource.com/c/go/+/212597
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/io')
-rw-r--r-- | src/io/ioutil/tempfile.go | 19 | ||||
-rw-r--r-- | src/io/ioutil/tempfile_test.go | 79 |
2 files changed, 95 insertions, 3 deletions
diff --git a/src/io/ioutil/tempfile.go b/src/io/ioutil/tempfile.go index 3aa23c5f01..af7c6fd7c1 100644 --- a/src/io/ioutil/tempfile.go +++ b/src/io/ioutil/tempfile.go @@ -5,6 +5,7 @@ package ioutil import ( + "errors" "os" "path/filepath" "strconv" @@ -52,7 +53,10 @@ func TempFile(dir, pattern string) (f *os.File, err error) { dir = os.TempDir() } - prefix, suffix := prefixAndSuffix(pattern) + prefix, suffix, err := prefixAndSuffix(pattern) + if err != nil { + return + } nconflict := 0 for i := 0; i < 10000; i++ { @@ -71,9 +75,15 @@ func TempFile(dir, pattern string) (f *os.File, err error) { return } +var errPatternHasSeparator = errors.New("pattern contains path separator") + // prefixAndSuffix splits pattern by the last wildcard "*", if applicable, // returning prefix as the part before "*" and suffix as the part after "*". -func prefixAndSuffix(pattern string) (prefix, suffix string) { +func prefixAndSuffix(pattern string) (prefix, suffix string, err error) { + if strings.ContainsRune(pattern, os.PathSeparator) { + err = errPatternHasSeparator + return + } if pos := strings.LastIndex(pattern, "*"); pos != -1 { prefix, suffix = pattern[:pos], pattern[pos+1:] } else { @@ -96,7 +106,10 @@ func TempDir(dir, pattern string) (name string, err error) { dir = os.TempDir() } - prefix, suffix := prefixAndSuffix(pattern) + prefix, suffix, err := prefixAndSuffix(pattern) + if err != nil { + return + } nconflict := 0 for i := 0; i < 10000; i++ { diff --git a/src/io/ioutil/tempfile_test.go b/src/io/ioutil/tempfile_test.go index 698ebabee9..469d2c98b3 100644 --- a/src/io/ioutil/tempfile_test.go +++ b/src/io/ioutil/tempfile_test.go @@ -48,6 +48,48 @@ func TestTempFile_pattern(t *testing.T) { } } +func TestTempFile_BadPattern(t *testing.T) { + tmpDir, err := TempDir("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + const sep = string(os.PathSeparator) + tests := []struct { + pattern string + wantErr bool + } { + {"ioutil*test", false}, + {"ioutil_test*foo", false}, + {"ioutil_test" + sep + "foo", true}, + {"ioutil_test*" + sep + "foo", true}, + {"ioutil_test" + sep + "*foo", true}, + {sep + "ioutil_test" + sep + "*foo", true}, + {"ioutil_test*foo" + sep, true}, + } + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + tmpfile, err := TempFile(tmpDir, tt.pattern) + defer func() { + if tmpfile != nil { + tmpfile.Close() + } + }() + if tt.wantErr { + if err == nil { + t.Errorf("Expected an error for pattern %q", tt.pattern) + } + if g, w := err, errPatternHasSeparator; g != w { + t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } + } else if err != nil { + t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) + } + }) + } +} + func TestTempDir(t *testing.T) { name, err := TempDir("/_not_exists_", "foo") if name != "" || err == nil { @@ -112,3 +154,40 @@ func TestTempDir_BadDir(t *testing.T) { t.Errorf("TempDir error = %#v; want PathError for path %q satisifying os.IsNotExist", err, badDir) } } + +func TestTempDir_BadPattern(t *testing.T) { + tmpDir, err := TempDir("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + const sep = string(os.PathSeparator) + tests := []struct { + pattern string + wantErr bool + } { + {"ioutil*test", false}, + {"ioutil_test*foo", false}, + {"ioutil_test" + sep + "foo", true}, + {"ioutil_test*" + sep + "foo", true}, + {"ioutil_test" + sep + "*foo", true}, + {sep + "ioutil_test" + sep + "*foo", true}, + {"ioutil_test*foo" + sep, true}, + } + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + _, err := TempDir(tmpDir, tt.pattern) + if tt.wantErr { + if err == nil { + t.Errorf("Expected an error for pattern %q", tt.pattern) + } + if g, w := err, errPatternHasSeparator; g != w { + t.Errorf("Error mismatch: got %#v, want %#v for pattern %q", g, w, tt.pattern) + } + } else if err != nil { + t.Errorf("Unexpected error %v for pattern %q", err, tt.pattern) + } + }) + } +} |