internals_windows.go 2.9 KB

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