From b1b9937bc75f0db9c804838ecce9bb6792a42525 Mon Sep 17 00:00:00 2001 From: John Howard Date: Wed, 5 Sep 2018 16:38:25 -0700 Subject: [PATCH] Windows: Go1.11: Use long path names in build context (TestBuildSymlinkBreakout) Signed-off-by: John Howard --- integration-cli/docker_cli_build_test.go | 6 ++++++ pkg/system/path_unix.go | 10 ++++++++++ pkg/system/path_windows.go | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 pkg/system/path_unix.go create mode 100644 pkg/system/path_windows.go diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index f6d5fe23f3..fadf9ec7c8 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/internal/test/fakestorage" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/archive" + "github.com/docker/docker/pkg/system" "github.com/go-check/check" "github.com/moby/buildkit/frontend/dockerfile/command" "github.com/opencontainers/go-digest" @@ -3601,6 +3602,11 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) { name := "testbuildsymlinkbreakout" tmpdir, err := ioutil.TempDir("", name) c.Assert(err, check.IsNil) + + // See https://github.com/moby/moby/pull/37770 for reason for next line. + tmpdir, err = system.GetLongPathName(tmpdir) + c.Assert(err, check.IsNil) + defer os.RemoveAll(tmpdir) ctx := filepath.Join(tmpdir, "context") if err := os.MkdirAll(ctx, 0755); err != nil { diff --git a/pkg/system/path_unix.go b/pkg/system/path_unix.go new file mode 100644 index 0000000000..b0b93196a1 --- /dev/null +++ b/pkg/system/path_unix.go @@ -0,0 +1,10 @@ +// +build !windows + +package system // import "github.com/docker/docker/pkg/system" + +// GetLongPathName converts Windows short pathnames to full pathnames. +// For example C:\Users\ADMIN~1 --> C:\Users\Administrator. +// It is a no-op on non-Windows platforms +func GetLongPathName(path string) (string, error) { + return path, nil +} diff --git a/pkg/system/path_windows.go b/pkg/system/path_windows.go new file mode 100644 index 0000000000..188f2c2957 --- /dev/null +++ b/pkg/system/path_windows.go @@ -0,0 +1,24 @@ +package system // import "github.com/docker/docker/pkg/system" + +import "syscall" + +// GetLongPathName converts Windows short pathnames to full pathnames. +// For example C:\Users\ADMIN~1 --> C:\Users\Administrator. +// It is a no-op on non-Windows platforms +func GetLongPathName(path string) (string, error) { + // See https://groups.google.com/forum/#!topic/golang-dev/1tufzkruoTg + p := syscall.StringToUTF16(path) + b := p // GetLongPathName says we can reuse buffer + n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + if n > uint32(len(b)) { + b = make([]uint16, n) + _, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + } + return syscall.UTF16ToString(b), nil +}