1
0
mirror of https://github.com/golang/go synced 2024-11-26 11:58:07 -07:00

testing: drop unusual characters from TempDir directory name

Only use safe characters of the test name for the os.MkdirTemp pattern.
This currently includes the alphanumeric characters and ASCII
punctuation characters known not to interact with globs.

Fixes #46624

Change-Id: I402c34775b943fed9b97963c52f79245cc16dc1d
Reviewed-on: https://go-review.googlesource.com/c/go/+/326010
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Tobias Klauser 2021-06-08 15:33:54 +02:00 committed by Tobias Klauser
parent b0355a3e72
commit 97cee43c93
2 changed files with 31 additions and 13 deletions

View File

@ -252,6 +252,8 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
"unicode"
"unicode/utf8"
) )
var initRan bool var initRan bool
@ -908,11 +910,6 @@ func (c *common) Cleanup(f func()) {
c.cleanups = append(c.cleanups, fn) c.cleanups = append(c.cleanups, fn)
} }
var tempDirReplacer struct {
sync.Once
r *strings.Replacer
}
// TempDir returns a temporary directory for the test to use. // TempDir returns a temporary directory for the test to use.
// The directory is automatically removed by Cleanup when the test and // The directory is automatically removed by Cleanup when the test and
// all its subtests complete. // all its subtests complete.
@ -936,13 +933,26 @@ func (c *common) TempDir() string {
if nonExistent { if nonExistent {
c.Helper() c.Helper()
// os.MkdirTemp doesn't like path separators in its pattern, // Drop unusual characters (such as path separators or
// so mangle the name to accommodate subtests. // characters interacting with globs) from the directory name to
tempDirReplacer.Do(func() { // avoid surprising os.MkdirTemp behavior.
tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_") mapper := func(r rune) rune {
}) if r < utf8.RuneSelf {
pattern := tempDirReplacer.r.Replace(c.Name()) const allowed = "!#$%&()+,-.=@^_{}~ "
if '0' <= r && r <= '9' ||
'a' <= r && r <= 'z' ||
'A' <= r && r <= 'Z' {
return r
}
if strings.ContainsRune(allowed, r) {
return r
}
} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
return r
}
return -1
}
pattern := strings.Map(mapper, c.Name())
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern) c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
if c.tempDirErr == nil { if c.tempDirErr == nil {
c.Cleanup(func() { c.Cleanup(func() {

View File

@ -58,6 +58,9 @@ func TestTempDir(t *testing.T) {
t.Run("test:subtest", testTempDir) t.Run("test:subtest", testTempDir)
t.Run("test/..", testTempDir) t.Run("test/..", testTempDir)
t.Run("../test", testTempDir) t.Run("../test", testTempDir)
t.Run("test[]", testTempDir)
t.Run("test*", testTempDir)
t.Run("äöüéè", testTempDir)
} }
func testTempDir(t *testing.T) { func testTempDir(t *testing.T) {
@ -74,7 +77,7 @@ func testTempDir(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir()) t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
default: default:
if !t.Failed() { if !t.Failed() {
t.Fatal("never received dir channel") t.Fatal("never received dir channel")
@ -108,6 +111,11 @@ func testTempDir(t *testing.T) {
if len(files) > 0 { if len(files) > 0 {
t.Errorf("unexpected %d files in TempDir: %v", len(files), files) t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
} }
glob := filepath.Join(dir, "*.txt")
if _, err := filepath.Glob(glob); err != nil {
t.Error(err)
}
} }
func TestSetenv(t *testing.T) { func TestSetenv(t *testing.T) {