Skip to content

Commit 97cee43

Browse files
committed
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 <[email protected]> Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent b0355a3 commit 97cee43

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

src/testing/testing.go

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ import (
252252
"sync"
253253
"sync/atomic"
254254
"time"
255+
"unicode"
256+
"unicode/utf8"
255257
)
256258

257259
var initRan bool
@@ -908,11 +910,6 @@ func (c *common) Cleanup(f func()) {
908910
c.cleanups = append(c.cleanups, fn)
909911
}
910912

911-
var tempDirReplacer struct {
912-
sync.Once
913-
r *strings.Replacer
914-
}
915-
916913
// TempDir returns a temporary directory for the test to use.
917914
// The directory is automatically removed by Cleanup when the test and
918915
// all its subtests complete.
@@ -936,13 +933,26 @@ func (c *common) TempDir() string {
936933
if nonExistent {
937934
c.Helper()
938935

939-
// os.MkdirTemp doesn't like path separators in its pattern,
940-
// so mangle the name to accommodate subtests.
941-
tempDirReplacer.Do(func() {
942-
tempDirReplacer.r = strings.NewReplacer("/", "_", "\\", "_", ":", "_")
943-
})
944-
pattern := tempDirReplacer.r.Replace(c.Name())
945-
936+
// Drop unusual characters (such as path separators or
937+
// characters interacting with globs) from the directory name to
938+
// avoid surprising os.MkdirTemp behavior.
939+
mapper := func(r rune) rune {
940+
if r < utf8.RuneSelf {
941+
const allowed = "!#$%&()+,-.=@^_{}~ "
942+
if '0' <= r && r <= '9' ||
943+
'a' <= r && r <= 'z' ||
944+
'A' <= r && r <= 'Z' {
945+
return r
946+
}
947+
if strings.ContainsRune(allowed, r) {
948+
return r
949+
}
950+
} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
951+
return r
952+
}
953+
return -1
954+
}
955+
pattern := strings.Map(mapper, c.Name())
946956
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
947957
if c.tempDirErr == nil {
948958
c.Cleanup(func() {

src/testing/testing_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func TestTempDir(t *testing.T) {
5858
t.Run("test:subtest", testTempDir)
5959
t.Run("test/..", testTempDir)
6060
t.Run("../test", testTempDir)
61+
t.Run("test[]", testTempDir)
62+
t.Run("test*", testTempDir)
63+
t.Run("äöüéè", testTempDir)
6164
}
6265

6366
func testTempDir(t *testing.T) {
@@ -74,7 +77,7 @@ func testTempDir(t *testing.T) {
7477
if err != nil {
7578
t.Fatal(err)
7679
}
77-
t.Errorf("directory %q stil exists: %v, isDir=%v", dir, fi, fi.IsDir())
80+
t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
7881
default:
7982
if !t.Failed() {
8083
t.Fatal("never received dir channel")
@@ -108,6 +111,11 @@ func testTempDir(t *testing.T) {
108111
if len(files) > 0 {
109112
t.Errorf("unexpected %d files in TempDir: %v", len(files), files)
110113
}
114+
115+
glob := filepath.Join(dir, "*.txt")
116+
if _, err := filepath.Glob(glob); err != nil {
117+
t.Error(err)
118+
}
111119
}
112120

113121
func TestSetenv(t *testing.T) {

0 commit comments

Comments
 (0)