-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't try to copy files over themselves
When copying a config module, make sure the full path for src and dst files don't match, and also check the inode in case we resolved a different path to the same file. Make a note about the unsafe usage of reusing a tempDir path.
- Loading branch information
Showing
2 changed files
with
50 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"os" | ||
"path/filepath" | ||
"strings" | ||
"syscall" | ||
) | ||
|
||
// copyDir copies the src directory contents into dst. Both directories | ||
|
@@ -19,6 +20,7 @@ func copyDir(dst, src string) error { | |
if err != nil { | ||
return err | ||
} | ||
|
||
if path == src { | ||
return nil | ||
} | ||
|
@@ -36,6 +38,19 @@ func copyDir(dst, src string) error { | |
// destination with the path without the src on it. | ||
dstPath := filepath.Join(dst, path[len(src):]) | ||
|
||
// we don't want to try and copy the same file over itself. | ||
if path == dstPath { | ||
return nil | ||
} | ||
|
||
// We still might have the same file through a link, so check the | ||
// inode if we can | ||
if eq, err := sameInode(path, dstPath); eq { | ||
return nil | ||
} else if err != nil { | ||
return err | ||
} | ||
|
||
// If we have a directory, make that subdirectory, then continue | ||
// the walk. | ||
if info.IsDir() { | ||
|
@@ -74,3 +89,36 @@ func copyDir(dst, src string) error { | |
|
||
return filepath.Walk(src, walkFn) | ||
} | ||
|
||
// sameInode looks up the inode for paths a and b and returns if they are | ||
// equal. On windows this will always return false. | ||
func sameInode(a, b string) (bool, error) { | ||
var aIno, bIno uint64 | ||
aStat, err := os.Stat(a) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
return false, nil | ||
} | ||
return false, err | ||
} | ||
if st, ok := aStat.Sys().(*syscall.Stat_t); ok { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
jbardin
Author
Member
|
||
aIno = st.Ino | ||
} | ||
|
||
bStat, err := os.Stat(b) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
return false, nil | ||
} | ||
return false, err | ||
} | ||
if st, ok := bStat.Sys().(*syscall.Stat_t); ok { | ||
bIno = st.Ino | ||
} | ||
|
||
if aIno > 0 && aIno == bIno { | ||
return true, nil | ||
} | ||
|
||
return false, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is breaking on windows builds.
syscall.Stat_t
does not exist