spf13 / afero

A FileSystem Abstraction System for Go
Apache License 2.0
5.8k stars 498 forks source link

BasePathFs throws `os.ErrNotExist` when basepath is `.` #344

Open raygecao opened 2 years ago

raygecao commented 2 years ago

Code:

func test(t *testing.T) {
    path := "."
    //path, _ = filepath.Abs(path)
    fs := afero.NewBasePathFs(afero.NewOsFs(), path)
    assert.NoError(t, afero.WriteFile(fs, "aaa", []byte("ttt"), 0o755))
}

Result:

openfile aaa: file does not exist

When cancel the comment in the second lines, it works well.

Reason:

when use RealPath for validating whether the filename is outside the fs (such as ../aaa), it filter the specified identifier ..

filepath.Clean(./aaa) => aaa which doesn't have a prefix of the base path .

https://github.com/spf13/afero/blob/450b30f2bfc09acd88c31d66c28cb814a14b192b/basepath.go#L40-L54

jxsl13 commented 2 years ago

base path assumes that your path is prefixed (manually) with the 'base path' contrary to your whole filesystem living inside of the base path directory without you having to provide the actual 'base path'.

try filepath.Join(path, "aaa")

if you are looking for a variant where you do not need to provide the actual path prefix, then check out my github.com/jxsl13/backupfs -> PrefixFs implementation.

BasePath cannot really work with relative paths, especially not when you are wrapping a remote server filesystem in BasepathFs where you are usually not in any kind of path that might be assumed as your working directory.