Browse code

Fix for Daemon crashing when wildcards are used for COPY/ADD in the filename and the command itself

Closes #12267

Signed-off-by: Doug Davis <dug@us.ibm.com>

Doug Davis authored on 2015/04/11 04:39:42
Showing 3 changed files
... ...
@@ -156,6 +156,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
156 156
 			dest,
157 157
 			allowRemote,
158 158
 			allowDecompression,
159
+			true,
159 160
 		); err != nil {
160 161
 			return err
161 162
 		}
... ...
@@ -226,7 +227,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
226 226
 	return nil
227 227
 }
228 228
 
229
-func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath string, destPath string, allowRemote bool, allowDecompression bool) error {
229
+func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath string, destPath string, allowRemote bool, allowDecompression bool, allowWildcards bool) error {
230 230
 
231 231
 	if origPath != "" && origPath[0] == '/' && len(origPath) > 1 {
232 232
 		origPath = origPath[1:]
... ...
@@ -351,7 +352,7 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
351 351
 	}
352 352
 
353 353
 	// Deal with wildcards
354
-	if ContainsWildcards(origPath) {
354
+	if allowWildcards && ContainsWildcards(origPath) {
355 355
 		for _, fileInfo := range b.context.GetSums() {
356 356
 			if fileInfo.Name() == "" {
357 357
 				continue
... ...
@@ -361,7 +362,9 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
361 361
 				continue
362 362
 			}
363 363
 
364
-			calcCopyInfo(b, cmdName, cInfos, fileInfo.Name(), destPath, allowRemote, allowDecompression)
364
+			// Note we set allowWildcards to false in case the name has
365
+			// a * in it
366
+			calcCopyInfo(b, cmdName, cInfos, fileInfo.Name(), destPath, allowRemote, allowDecompression, false)
365 367
 		}
366 368
 		return nil
367 369
 	}
... ...
@@ -1113,10 +1113,10 @@ func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) {
1113 1113
 			"dir/nested_dir/nest_nest_file": "2 times nested",
1114 1114
 			"dirt": "dirty",
1115 1115
 		})
1116
-	defer ctx.Close()
1117 1116
 	if err != nil {
1118 1117
 		c.Fatal(err)
1119 1118
 	}
1119
+	defer ctx.Close()
1120 1120
 
1121 1121
 	id1, err := buildImageFromContext(name, ctx, true)
1122 1122
 	if err != nil {
... ...
@@ -1155,6 +1155,31 @@ func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) {
1155 1155
 
1156 1156
 }
1157 1157
 
1158
+func (s *DockerSuite) TestBuildCopyWildcardInName(c *check.C) {
1159
+	name := "testcopywildcardinname"
1160
+	defer deleteImages(name)
1161
+	ctx, err := fakeContext(`FROM busybox
1162
+	COPY *.txt /tmp/
1163
+	RUN [ "$(cat /tmp/\*.txt)" = 'hi there' ]
1164
+	`, map[string]string{"*.txt": "hi there"})
1165
+
1166
+	if err != nil {
1167
+		// Normally we would do c.Fatal(err) here but given that
1168
+		// the odds of this failing are so rare, it must be because
1169
+		// the OS we're running the client on doesn't support * in
1170
+		// filenames (like windows).  So, instead of failing the test
1171
+		// just let it pass. Then we don't need to explicitly
1172
+		// say which OSs this works on or not.
1173
+		return
1174
+	}
1175
+	defer ctx.Close()
1176
+
1177
+	_, err = buildImageFromContext(name, ctx, true)
1178
+	if err != nil {
1179
+		c.Fatalf("should have built: %q", err)
1180
+	}
1181
+}
1182
+
1158 1183
 func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) {
1159 1184
 	name := "testcopywildcardcache"
1160 1185
 	ctx, err := fakeContext(`FROM busybox
... ...
@@ -663,7 +663,6 @@ func fakeContextAddDockerfile(ctx *FakeContext, dockerfile string) error {
663 663
 func fakeContext(dockerfile string, files map[string]string) (*FakeContext, error) {
664 664
 	ctx, err := fakeContextWithFiles(files)
665 665
 	if err != nil {
666
-		ctx.Close()
667 666
 		return nil, err
668 667
 	}
669 668
 	if err := fakeContextAddDockerfile(ctx, dockerfile); err != nil {