Skip to content

Commit 978d263

Browse files
committed
chore: extensive checking and error handling for EvalSymlinks
1 parent 49752e1 commit 978d263

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

copy_dir.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@ func mode(mode, umask os.FileMode) os.FileMode {
1717
return mode & ^umask
1818
}
1919

20+
func safeEvalSymlinks(path string) (string, error) {
21+
resolved, err := filepath.EvalSymlinks(path)
22+
if err == nil || runtime.GOOS != "windows" {
23+
return resolved, err
24+
}
25+
26+
// On Windows with Go 1.23+, EvalSymlinks may not resolve junctions
27+
fi, statErr := os.Lstat(path)
28+
if statErr != nil {
29+
return "", err // fallback to original error
30+
}
31+
32+
if fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0 {
33+
// Accept it as a reparse point (symlink or junction)
34+
return path, nil
35+
}
36+
37+
return "", err
38+
}
39+
2040
// copyDir copies the src directory contents into dst. Both directories
2141
// should already exist.
2242
//
@@ -25,13 +45,9 @@ func copyDir(ctx context.Context, dst string, src string, ignoreDot bool, disabl
2545
// We can safely evaluate the symlinks here, even if disabled, because they
2646
// will be checked before actual use in walkFn and copyFile
2747
var err error
28-
resolved, err := filepath.EvalSymlinks(src)
48+
resolved, err := safeEvalSymlinks(src)
2949
if err != nil {
30-
if runtime.GOOS == "windows" {
31-
resolved = src
32-
} else {
33-
return err
34-
}
50+
return err
3551
}
3652

3753
// Check if the resolved path tries to escape upward from the original

0 commit comments

Comments
 (0)