spf13 / afero

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

BasePathFs wrongly trims path prefix. #428

Open movsb opened 2 weeks ago

movsb commented 2 weeks ago

It seems that BasePathFile.Name() method returns wrongly trimmed path:

https://github.com/spf13/afero/blob/5c4385aa20510dba5ca4db12c02b0c9211d82892/basepath.go#L37

filepath.Clean will have the last / removed, leaving the Name() containing a / prefix. Next time the BasePathFile trimming a prefix, it trims nothing: strings.TrimPrefix(`/123/afero-test-388191401`, `123`).

package main

import (
    "fmt"

    "github.com/spf13/afero"
)

func must1[A any](a A, e error) A {
    if e != nil {
        panic(e)
    }
    return a
}
func must(e error) {
    if e != nil {
        panic(e)
    }
}

func main() {
    osFs := afero.NewOsFs()
    must(osFs.MkdirAll(`files/123`, 0755))

    fs1 := afero.NewBasePathFs(osFs, `files`)
    fs2 := afero.NewBasePathFs(fs1, `123`)

    tmp := must1(afero.TempFile(fs2, `.`, `afero-test-*`))
    fmt.Println(`Path:`, tmp.Name())

    must(fs2.Chmod(tmp.Name(), 0644))
}

The code above will panic:

$ go run main.go
Path: /123/afero-test-388191401
panic: chmod files/123/123/afero-test-388191401: no such file or directory

goroutine 1 [running]:
main.must(...)
        /Users/.../code/tests/main.go:17
main.main()
        /Users/.../code/tests/main.go:31 +0x1b8
exit status 2

Update:

Chaning fs2 to be fs2 := afero.NewBasePathFs(fs1, `/123`) seems to work, but it's somewhat inconsistent.