Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os: Stat does not return error when path separators are added to end of an existing file path #33578

Closed
jonhadfield opened this issue Aug 10, 2019 · 9 comments

Comments

@jonhadfield
Copy link

@jonhadfield jonhadfield commented Aug 10, 2019

What version of Go are you using (go version)?

$ go version
go1.12.7 darwin/amd64

Does this issue reproduce with the latest release?

Yes.
Only tried on MacOS and Go Playground.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/hadfielj/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/hadfielj/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12.7/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12.7/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/hl/7d_9pbhj2n7_x2z1w1jhsy2m0000gn/T/go-build218481097=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Used os.Stat against a path that doesn't exist. The path was constructed by adding "/" to the end of a valid file path.
https://play.golang.org/p/6J4uiEC-UsG
You can add many trailing slashes and it still returns without error:
https://play.golang.org/p/gP_NBuzG74B

What did you expect to see?

Error to be:
stat <path>: No such file or directory

What did you see instead?

Error:
<nil>

@jonhadfield
Copy link
Author

@jonhadfield jonhadfield commented Aug 10, 2019

Edit: Following is in response to suggestion (now removed) by other user that provided this URL: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266

Interesting. It's inconsistent with how Linux and MacOS work though:

$ touch test
$ stat test
  File: ‘test’
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: ca01h/51713d	Inode: 262802      Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  501/hadfielj)   Gid: (  501/hadfielj)
...
$ stat test/
stat: cannot stat ‘test/’: Not a directory

Unless the OS' stat is not comparable?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Aug 11, 2019

On GNU/Linux I get an error not a directory. I agree that I don't see this error on the playground, but the playground isn't using a real file system.

If you don't see this on macOS then I think macOS must work differently. Try writing the equivalent C program and see what happens.

@jonhadfield
Copy link
Author

@jonhadfield jonhadfield commented Aug 11, 2019

Equivalent C program shows consistent result for both Linux and MacOS, i.e. if I add a trailing slash to the end of an existing file path when calling stat, it fails to stat the file.
Code used:

#include <stdio.h>
#include <sys/stat.h>

int main() {
    struct stat stats;
    char path[11] = "hello.txt/";
    if (stat(path, &stats) == 0)
    {
        printf("'%s' does exist\n", path);
    }
    else
    {
        printf("'%s' does not exist\n", path);
    }
    return 0;
}

On MacOS and Linux, when run in the same directory as a file called 'hello.txt', it returns:
'hello.txt/' does not exist

@gregory-m
Copy link
Contributor

@gregory-m gregory-m commented Aug 18, 2019

What version of MacOS are you using?

I can't reproduce the issue with go 1.12.9 and Mac OS 10.14.6:

⇢ $ sw_vers                                                                                                                                                                                                                                    2 ↵
go version

cat > t.go <<EOL
package main

import (
        "fmt"
        "io/ioutil"
        "os"
)

func main() {
        p := fmt.Sprintf("%s/hello.txt", os.TempDir())
        b := []byte("hello world")
        _ = ioutil.WriteFile(p, b, 0644)
        pWithSep := p + "/"
        _, err := os.Stat(pWithSep)
        fmt.Println(err)
}
EOL

go run t.go


ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G87
go version go1.12.9 darwin/amd64
stat /var/folders/mm/b3n2qsjx73lddzbw34x40w8w0000gn/T//hello.txt/: not a directory
@cuonglm
Copy link
Contributor

@cuonglm cuonglm commented Aug 18, 2019

/me can not reproduce with Mac OS 10.14.6, go 1.12.8, 1.12.9 and tip.

@jonhadfield
Copy link
Author

@jonhadfield jonhadfield commented Aug 18, 2019

Original test carried out on MacOS 10.15 Beta with 1.12.7.
I cannot reproduce:

  • since updating to 1.12.9
  • downgrading to 1.12.7 using official installer, rather than homebrew version

Homebrew formula for 1.12.7 now missing, so unable to check if it was that specific build/env setup.
Will close for now and reopen if I manage to get homebrew 1.12.7 and am able to reproduce.

@gregory-m
Copy link
Contributor

@gregory-m gregory-m commented Aug 18, 2019

Try this:

brew unlink go
cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core/Formula
git checkout fa46027fe
HOMEBREW_NO_AUTO_UPDATE=1 brew install go
@jonhadfield
Copy link
Author

@jonhadfield jonhadfield commented Aug 18, 2019

Thanks for the instructions @gregory-m.
I'm able to test again with 1.12.7 but no longer able to reproduce the issue. I even ensured my 'go env' was identical to what I reported above, but no luck.
Can only assume something else has changed on my machine.

@gregory-m
Copy link
Contributor

@gregory-m gregory-m commented Aug 19, 2019

@jonhadfield Thank you for fast response.
Maybe this is just fluctuations of solar radiation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.