diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index 2e457e7424..28c9dc09e2 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -3022,14 +3022,17 @@ func (s *DockerSuite) TestBuildOnBuild(c *check.C) { // gh #2446 func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) { - testRequires(c, DaemonIsLinux) + makeLink := `ln -s /foo /bar` + if daemonPlatform == "windows" { + makeLink = `mklink /D C:\bar C:\foo` + } name := "testbuildaddtosymlinkdest" ctx, err := fakeContext(`FROM busybox - RUN mkdir /foo - RUN ln -s /foo /bar + RUN sh -c "mkdir /foo" + RUN `+makeLink+` ADD foo /bar/ - RUN [ -f /bar/foo ] - RUN [ -f /foo/foo ]`, + RUN sh -c "[ -f /bar/foo ]" + RUN sh -c "[ -f /foo/foo ]"`, map[string]string{ "foo": "hello", }) diff --git a/components/engine/pkg/symlink/fs.go b/components/engine/pkg/symlink/fs.go index dcf707f426..f6bc2231f6 100644 --- a/components/engine/pkg/symlink/fs.go +++ b/components/engine/pkg/symlink/fs.go @@ -95,8 +95,8 @@ func evalSymlinksInScope(path, root string) (string, error) { // root gets prepended and we Clean again (to remove any trailing slash // if the first Clean gave us just "/") cleanP := filepath.Clean(string(filepath.Separator) + b.String() + p) - if cleanP == string(filepath.Separator) { - // never Lstat "/" itself + if isDriveOrRoot(cleanP) { + // never Lstat "/" itself, or drive letters on Windows b.Reset() continue } @@ -113,7 +113,8 @@ func evalSymlinksInScope(path, root string) (string, error) { return "", err } if fi.Mode()&os.ModeSymlink == 0 { - b.WriteString(p + string(filepath.Separator)) + b.WriteString(p) + b.WriteRune(filepath.Separator) continue } diff --git a/components/engine/pkg/symlink/fs_unix.go b/components/engine/pkg/symlink/fs_unix.go index 818004f26c..22708273d6 100644 --- a/components/engine/pkg/symlink/fs_unix.go +++ b/components/engine/pkg/symlink/fs_unix.go @@ -9,3 +9,7 @@ import ( func evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) } + +func isDriveOrRoot(p string) bool { + return p == string(filepath.Separator) +} diff --git a/components/engine/pkg/symlink/fs_windows.go b/components/engine/pkg/symlink/fs_windows.go index 449fe56483..241e531f9d 100644 --- a/components/engine/pkg/symlink/fs_windows.go +++ b/components/engine/pkg/symlink/fs_windows.go @@ -153,3 +153,17 @@ func walkSymlinks(path string) (string, error) { } return filepath.Clean(b.String()), nil } + +func isDriveOrRoot(p string) bool { + if p == string(filepath.Separator) { + return true + } + + length := len(p) + if length >= 2 { + if p[length-1] == ':' && (('a' <= p[length-2] && p[length-2] <= 'z') || ('A' <= p[length-2] && p[length-2] <= 'Z')) { + return true + } + } + return false +}