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:
parent
c3db64c0f4
commit
ba4c6d1d6e
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user