Browse code

Don't attempt to evaluate drive root on Windows

Signed-off-by: Darren Stahl <darst@microsoft.com>

Darren Stahl authored on 2016/09/08 10:20:51
Showing 4 changed files
... ...
@@ -3022,14 +3022,17 @@ func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
3022 3022
 
3023 3023
 // gh #2446
3024 3024
 func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
3025
-	testRequires(c, DaemonIsLinux)
3025
+	makeLink := `ln -s /foo /bar`
3026
+	if daemonPlatform == "windows" {
3027
+		makeLink = `mklink /D C:\bar C:\foo`
3028
+	}
3026 3029
 	name := "testbuildaddtosymlinkdest"
3027 3030
 	ctx, err := fakeContext(`FROM busybox
3028
-        RUN mkdir /foo
3029
-        RUN ln -s /foo /bar
3031
+        RUN sh -c "mkdir /foo"
3032
+        RUN `+makeLink+`
3030 3033
         ADD foo /bar/
3031
-        RUN [ -f /bar/foo ]
3032
-        RUN [ -f /foo/foo ]`,
3034
+        RUN sh -c "[ -f /bar/foo ]"
3035
+        RUN sh -c "[ -f /foo/foo ]"`,
3033 3036
 		map[string]string{
3034 3037
 			"foo": "hello",
3035 3038
 		})
... ...
@@ -95,8 +95,8 @@ func evalSymlinksInScope(path, root string) (string, error) {
95 95
 		// root gets prepended and we Clean again (to remove any trailing slash
96 96
 		// if the first Clean gave us just "/")
97 97
 		cleanP := filepath.Clean(string(filepath.Separator) + b.String() + p)
98
-		if cleanP == string(filepath.Separator) {
99
-			// never Lstat "/" itself
98
+		if isDriveOrRoot(cleanP) {
99
+			// never Lstat "/" itself, or drive letters on Windows
100 100
 			b.Reset()
101 101
 			continue
102 102
 		}
... ...
@@ -113,7 +113,8 @@ func evalSymlinksInScope(path, root string) (string, error) {
113 113
 			return "", err
114 114
 		}
115 115
 		if fi.Mode()&os.ModeSymlink == 0 {
116
-			b.WriteString(p + string(filepath.Separator))
116
+			b.WriteString(p)
117
+			b.WriteRune(filepath.Separator)
117 118
 			continue
118 119
 		}
119 120
 
... ...
@@ -9,3 +9,7 @@ import (
9 9
 func evalSymlinks(path string) (string, error) {
10 10
 	return filepath.EvalSymlinks(path)
11 11
 }
12
+
13
+func isDriveOrRoot(p string) bool {
14
+	return p == string(filepath.Separator)
15
+}
... ...
@@ -153,3 +153,17 @@ func walkSymlinks(path string) (string, error) {
153 153
 	}
154 154
 	return filepath.Clean(b.String()), nil
155 155
 }
156
+
157
+func isDriveOrRoot(p string) bool {
158
+	if p == string(filepath.Separator) {
159
+		return true
160
+	}
161
+
162
+	length := len(p)
163
+	if length >= 2 {
164
+		if p[length-1] == ':' && (('a' <= p[length-2] && p[length-2] <= 'z') || ('A' <= p[length-2] && p[length-2] <= 'Z')) {
165
+			return true
166
+		}
167
+	}
168
+	return false
169
+}