go ``` archive/zip: Reader.Open lies about directory fs.FileMode ```

9njqaruj  于 6个月前  发布在  Go
关注(0)|答案(3)|浏览(58)

你使用的Go版本是什么( go version )?

$ go version
go version go1.17 linux/amd64

这个问题在最新版本中是否重现?

是的

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/user/go/pkg/mod"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2958766942=/tmp/go-build -gno-record-gcc-switches"

你做了什么?

https://play.golang.org/p/-MVV8qRhxxC 大致如下:

r, _ := NewReader(b, len)
f, _ := r.Open("path/to/dir")
s, _ := f.Stat()
fmt.Print(s.Mode())

你期望看到什么?

drw-rw-rw- (来自 zip.File.FileHeader.Mode() 的推导)

你看到了什么?

dr-xr-xr-x

额外的上下文?

似乎 Reader.Open ,特别是 fileListEntry.Mode 的实现,而不是返回 fileListEntry.file.FileHeader.Mode 中实际包含的模式,而是返回一个硬编码的 fs.FileMode :

package zip // import "archive/zip"

func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }

我猜想,但看起来这是因为 fileListEntry.file 在目录条目为合成时可以是 nil ,例如zip文件包含一个没有目录文件指向它的文件,参见 #48084
如果我们想一举两得,因为这将是一个明确的信号表明“目录文件丢失”,我认为合理的方法是:(尽管这是一个破坏性的变化)

package zip // import "archive/zip"

func (f *fileListEntry) Mode() fs.FileMode {
        if f.file == nil {
                return 0
        }
        return f.file.FileHeader.Mode
}
hec6srdp

hec6srdp1#

cc @rolandshoemaker@dsnet

f4t66c6m

f4t66c6m2#

我认为目录的可执行位通常意味着你可以进入该目录,所以对我来说0555是有意义的。你为什么期待drw-rw-rw-?
0555来自CL https://go-review.googlesource.com/c/go/+/243937.cc @rsc

5lhxktic

5lhxktic3#

所以,这是一个不太好的复制器,因为我同时使用了Writer.Create作为文件和目录的模式,因此我们得到了一个"默认"模式。我可以很高兴地修改示例以进行完整的Writer.CreateHeader并设置自定义模式,但这似乎是一个最小可行的复制器。
我的评论并不是说drw-rw-rw-(0o20000000555)比drw-rw-rw-(0o20000000666)更好或更差,而是说存储在b中的zip字节定义了dir/具有drw-rw-rw-的模式,因此这就是archive/zip应该为Reader.FileReader.Open返回的内容。

相关问题