51 lines
1.1 KiB
Go
51 lines
1.1 KiB
Go
package engine
|
|
|
|
import (
|
|
"errors"
|
|
"io/fs"
|
|
)
|
|
|
|
var errImportDirectoryEntryLimit = errors.New("import directory-entry visit limit reached")
|
|
|
|
// visitBoundedImportDirectory shares entry accounting across directory and glob searches.
|
|
func visitBoundedImportDirectory(access *filesystemAccess, directory string, limit int, accounting *importAccounting, visit func(fs.DirEntry) error) error {
|
|
if accounting == nil {
|
|
accounting = &importAccounting{}
|
|
}
|
|
var visitError error
|
|
err := access.readDirectory(directory, func(entry fs.DirEntry) bool {
|
|
accounting.entries++
|
|
if accounting.entries > limit {
|
|
visitError = errImportDirectoryEntryLimit
|
|
return false
|
|
}
|
|
if err := visit(entry); err != nil {
|
|
visitError = err
|
|
return false
|
|
}
|
|
return true
|
|
})
|
|
if visitError != nil {
|
|
return visitError
|
|
}
|
|
return err
|
|
}
|
|
|
|
func importDirectoryEntryIsDirectory(entry fs.DirEntry) (bool, error) {
|
|
mode := entry.Type()
|
|
if mode&fs.ModeSymlink != 0 {
|
|
return false, nil
|
|
}
|
|
if mode.IsDir() {
|
|
return true, nil
|
|
}
|
|
if mode != 0 {
|
|
return false, nil
|
|
}
|
|
info, err := entry.Info()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return info.IsDir(), nil
|
|
}
|