Go version
master
Output of go env
in your module/workspace:
$ go env
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/dneil/Library/Caches/go-build'
GOENV='/Users/dneil/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/dneil/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/dneil'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/dneil/src/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/dneil/src/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='devel go1.24-adf220a5d5 Mon Sep 9 17:11:52 2024 +0000'
GODEBUG=''
GOTELEMETRY='on'
GOTELEMETRYDIR='/Users/dneil/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/tmp/m2/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/kw/0t4d_x2n4plg9157krpjtxmw0047mf/T/go-build1969548244=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
package main
import (
"fmt"
"os"
)
func main() {
_, err := os.Open("file/.")
fmt.Println(err)
}
$ touch file
$ go run main.go
open file/.: not a directory
$ GOOS=wasip1 GOARCH=wasm go run main.go
<nil>
What did you see happen?
When built with GOOS=wasip1, the os package performs some path cleaning on filenames which results in a terminal "/." being removed. This causes opening a non-directory file to unexpectedly succeed.
What did you expect to see?
An error opening "file/.", because "file" is not a directory.
Comment From: gabyhelp
Related Issues and Documentation
- os: Windows-style absolute paths are not recognized correctly in wasm environments #68820 (closed)
- os: `GOOS=wasip1 GOARCH=wasm` the `ReadFile` function gives `-1` as the `rootFd` to `path_open` causing `Bad file number` error #63466
- io/fs,os: fs.ReadDir with an os.DirFS can produce invalid paths #44166 (closed)
- path/filepath: WalkDir pass unclean path to WalkDirFunc while using unclean root #50629
- fs.Stat+os.DirFS gives an error but os.Stat works #44297 (closed)
- os: Stat does not return error when path separators are added to end of an existing file path #33578 (closed)
- os: os.DirFS doesn't work with Windows UNC paths #54694 (closed)
- os: document that fs.ReadDirFile.ReadDir doesn't restart each time #69301
- Unexpected result from filepath.Dir #37890 (closed)
- affected/package: io/fs #57772 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: neild
Hmm, the problem seems to be that wasip1 is performing path cleaning in general prior to opening files, which is going to affect more than just a trailing "/.".
This produces incorrect results in a variety of situations, or at least results inconsistent with the usual behavior of Unix filesystems.
Open("a/../b")
should be an error if a does not exist, or is a non-directory file.Open("symlink/../b")
should resolve any symlink in the first path component, and then open b in the parent of the linked-to directory.Open("a/")
should be an error if a is a non-directory file.
Testing with wasmtime, the WASI file API functions all seem to behave as I'd expect here (modulo what seems to be one bug: https://github.com/bytecodealliance/wasmtime/issues/9272). The additional path-cleaning behavior is being added in the Go runtime, and I don't believe it's correct.
Comment From: cagedmantis
cc @rsc @ianlancetaylor @bradfitz @griesemer
Comment From: Zxilly
I sent a patch that fixes file/.
issue, but I need to investigate further for subsequent issues.
Comment From: gopherbot
Change https://go.dev/cl/614083 mentions this issue: syscall: add separator for filepath if contains "." in waspi