1
0
mirror of https://github.com/golang/go synced 2024-11-11 18:51:37 -07:00

syscall: Fix Getwd on Windows to correctly handle long paths.

Fixes #60051.

Change-Id: Ia68ca0493912cb09d8c1d36a144bf0725842af1d
Reviewed-on: https://go-review.googlesource.com/c/go/+/502415
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
Qi Xiao 2023-06-11 23:29:26 +01:00 committed by Gopher Robot
parent c3db64c0f4
commit ba4c6d1d6e
2 changed files with 38 additions and 4 deletions

View File

@ -533,11 +533,21 @@ const ImplementsGetwd = true
func Getwd() (wd string, err error) {
b := make([]uint16, 300)
n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
if e != nil {
return "", e
// The path of the current directory may not fit in the initial 300-word
// buffer when long path support is enabled. The current directory may also
// change between subsequent calls of GetCurrentDirectory. As a result, we
// need to retry the call in a loop until the current directory fits, each
// time with a bigger buffer.
for {
n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
if e != nil {
return "", e
}
if int(n) <= len(b) {
return UTF16ToString(b[:n]), nil
}
b = make([]uint16, n)
}
return UTF16ToString(b[0:n]), nil
}
func Chdir(path string) (err error) {

View File

@ -180,6 +180,30 @@ int main(int argc, char *argv[])
}
}
func TestGetwd_DoesNotPanicWhenPathIsLong(t *testing.T) {
// Regression test for https://github.com/golang/go/issues/60051.
// The length of a filename is also limited, so we can't reproduce the
// crash by creating a single directory with a very long name; we need two
// layers.
a200 := strings.Repeat("a", 200)
dirname := filepath.Join(t.TempDir(), a200, a200)
err := os.MkdirAll(dirname, 0o700)
if err != nil {
t.Skipf("MkdirAll failed: %v", err)
}
err = os.Chdir(dirname)
if err != nil {
t.Skipf("Chdir failed: %v", err)
}
// Change out of the temporary directory so that we don't inhibit its
// removal during test cleanup.
defer os.Chdir(`\`)
syscall.Getwd()
}
func FuzzUTF16FromString(f *testing.F) {
f.Add("hi") // ASCII
f.Add("â") // latin1