github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/builder/dockerfile/internals_windows.go (about) 1 package dockerfile 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/docker/docker/pkg/system" 10 "github.com/pkg/errors" 11 ) 12 13 // normaliseDest normalises the destination of a COPY/ADD command in a 14 // platform semantically consistent way. 15 func normaliseDest(cmdName, workingDir, requested string) (string, error) { 16 dest := filepath.FromSlash(requested) 17 endsInSlash := strings.HasSuffix(dest, string(os.PathSeparator)) 18 19 // We are guaranteed that the working directory is already consistent, 20 // However, Windows also has, for now, the limitation that ADD/COPY can 21 // only be done to the system drive, not any drives that might be present 22 // as a result of a bind mount. 23 // 24 // So... if the path requested is Linux-style absolute (/foo or \\foo), 25 // we assume it is the system drive. If it is a Windows-style absolute 26 // (DRIVE:\\foo), error if DRIVE is not C. And finally, ensure we 27 // strip any configured working directories drive letter so that it 28 // can be subsequently legitimately converted to a Windows volume-style 29 // pathname. 30 31 // Not a typo - filepath.IsAbs, not system.IsAbs on this next check as 32 // we only want to validate where the DriveColon part has been supplied. 33 if filepath.IsAbs(dest) { 34 if strings.ToUpper(string(dest[0])) != "C" { 35 return "", fmt.Errorf("Windows does not support %s with a destinations not on the system drive (C:)", cmdName) 36 } 37 dest = dest[2:] // Strip the drive letter 38 } 39 40 // Cannot handle relative where WorkingDir is not the system drive. 41 if len(workingDir) > 0 { 42 if ((len(workingDir) > 1) && !system.IsAbs(workingDir[2:])) || (len(workingDir) == 1) { 43 return "", fmt.Errorf("Current WorkingDir %s is not platform consistent", workingDir) 44 } 45 if !system.IsAbs(dest) { 46 if string(workingDir[0]) != "C" { 47 return "", fmt.Errorf("Windows does not support %s with relative paths when WORKDIR is not the system drive", cmdName) 48 } 49 dest = filepath.Join(string(os.PathSeparator), workingDir[2:], dest) 50 // Make sure we preserve any trailing slash 51 if endsInSlash { 52 dest += string(os.PathSeparator) 53 } 54 } 55 } 56 return dest, nil 57 } 58 59 func containsWildcards(name string) bool { 60 for i := 0; i < len(name); i++ { 61 ch := name[i] 62 if ch == '*' || ch == '?' || ch == '[' { 63 return true 64 } 65 } 66 return false 67 } 68 69 var pathBlacklist = map[string]bool{ 70 "c:\\": true, 71 "c:\\windows": true, 72 } 73 74 func validateCopySourcePath(imageSource *imageMount, origPath string) error { 75 // validate windows paths from other images 76 if imageSource == nil { 77 return nil 78 } 79 origPath = filepath.FromSlash(origPath) 80 p := strings.ToLower(filepath.Clean(origPath)) 81 if !filepath.IsAbs(p) { 82 if filepath.VolumeName(p) != "" { 83 if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths 84 p = p[:len(p)-1] 85 } 86 p += "\\" 87 } else { 88 p = filepath.Join("c:\\", p) 89 } 90 } 91 if _, blacklisted := pathBlacklist[p]; blacklisted { 92 return errors.New("copy from c:\\ or c:\\windows is not allowed on windows") 93 } 94 return nil 95 }