golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.97k stars 17.66k forks source link

os: Open("file/.") does not produce an error on wasip1 #69509

Open neild opened 1 month ago

neild commented 1 month ago

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.

gabyhelp commented 1 month ago

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

neild commented 1 month ago

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.

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.

cagedmantis commented 1 month ago

cc @rsc @ianlancetaylor @bradfitz @griesemer

Zxilly commented 1 month ago

I sent a patch that fixes file/. issue, but I need to investigate further for subsequent issues.

gopherbot commented 1 month ago

Change https://go.dev/cl/614083 mentions this issue: syscall: add separator for filepath if contains "." in waspi