Handle path resolution errors better in the file walker
This commit is contained in:
parent
4f1b0c67d6
commit
085a02726b
|
@ -26,7 +26,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error returned when there is a bad path provided to one of the FS calls.
|
// Error returned when there is a bad path provided to one of the FS calls.
|
||||||
var InvalidPathResolution = errors.New("invalid path resolution")
|
type PathResolutionError struct{}
|
||||||
|
|
||||||
|
// Returns the error response in a string form that can be more easily consumed.
|
||||||
|
func (pre PathResolutionError) Error() string {
|
||||||
|
return "invalid path resolution"
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsPathResolutionError(err error) bool {
|
||||||
|
_, ok := err.(PathResolutionError)
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
type Filesystem struct {
|
type Filesystem struct {
|
||||||
Server *Server
|
Server *Server
|
||||||
|
@ -87,7 +98,7 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
|
||||||
// attempt going on, and we should NOT resolve this path for them.
|
// attempt going on, and we should NOT resolve this path for them.
|
||||||
if nonExistentPathResolution != "" {
|
if nonExistentPathResolution != "" {
|
||||||
if !strings.HasPrefix(nonExistentPathResolution, fs.Path()) {
|
if !strings.HasPrefix(nonExistentPathResolution, fs.Path()) {
|
||||||
return "", InvalidPathResolution
|
return "", PathResolutionError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the nonExistentPathResolution variable is not empty then the initial path requested
|
// If the nonExistentPathResolution variable is not empty then the initial path requested
|
||||||
|
@ -104,7 +115,7 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", InvalidPathResolution
|
return "", PathResolutionError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to keep some of the codebase a little cleaner. Returns a "safe" version of the path
|
// Helper function to keep some of the codebase a little cleaner. Returns a "safe" version of the path
|
||||||
|
@ -246,7 +257,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
|
||||||
var size int64
|
var size int64
|
||||||
err := fs.Walk(dir, func(_ string, f os.FileInfo, err error) error {
|
err := fs.Walk(dir, func(_ string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fs.handleWalkerError(err, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.IsDir() {
|
if !f.IsDir() {
|
||||||
|
@ -707,7 +718,7 @@ func (fs *Filesystem) GetIncludedFiles(dir string, ignored []string) (*backup.In
|
||||||
|
|
||||||
if err := fs.Walk(cleaned, func(p string, f os.FileInfo, err error) error {
|
if err := fs.Walk(cleaned, func(p string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fs.handleWalkerError(err, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid unnecessary parsing if there are no ignored files, nothing will match anyways
|
// Avoid unnecessary parsing if there are no ignored files, nothing will match anyways
|
||||||
|
@ -764,7 +775,7 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
err := fs.Walk(p, func(s string, info os.FileInfo, err error) error {
|
err := fs.Walk(p, func(s string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fs.handleWalkerError(err, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.IsDir() {
|
if !info.IsDir() {
|
||||||
|
@ -788,3 +799,23 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er
|
||||||
|
|
||||||
return a.Create(d, context.Background())
|
return a.Create(d, context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle errors encountered when walking through directories.
|
||||||
|
//
|
||||||
|
// If there is a path resolution error just skip the item entirely. Only return this for a
|
||||||
|
// directory, otherwise return nil. Returning this error for a file will stop the walking
|
||||||
|
// for the remainder of the directory. This is assuming an os.FileInfo struct was even returned.
|
||||||
|
func (fs *Filesystem) handleWalkerError(err error, f os.FileInfo) error {
|
||||||
|
fmt.Println("handling walker error")
|
||||||
|
if !IsPathResolutionError(err) {
|
||||||
|
fmt.Println("not a path res error")
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if f != nil && f.IsDir() {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -62,7 +62,16 @@ func (w *PooledFileWalker) process(path string) error {
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
sp, err := w.Filesystem.SafeJoin(p, f)
|
sp, err := w.Filesystem.SafeJoin(p, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
// Let the callback function handle what to do if there is a path resolution error because a
|
||||||
|
// dangerous path was resolved. If there is an error returned, return from this entire process
|
||||||
|
// otherwise just skip over this specific file. We don't care if its a file or a directory at
|
||||||
|
// this point since either way we're skipping it, however, still check for the SkipDir since that
|
||||||
|
// would be thrown otherwise.
|
||||||
|
if err = w.callback(sp, f, err); err != nil && err != filepath.SkipDir {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
i, err := os.Stat(sp)
|
i, err := os.Stat(sp)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user