mirror of
https://github.com/golang/go
synced 2024-11-19 21:04:43 -07:00
archive/zip: support full range of FileMode flags
Zip files may actually store symlinks, and that's represented as a file with unix flag S_IFLNK and with its data containing the symlink target name. The other flags are being supported too. Now that the os package has the full range of flags in a system agnostic manner, there's no reason to discard that information. R=golang-dev, adg, rogpeppe CC=golang-dev https://golang.org/cl/5624048
This commit is contained in:
parent
419c53af30
commit
02fb021161
@ -69,8 +69,23 @@ var tests = []ZipTest{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{Name: "readme.zip"},
|
{
|
||||||
{Name: "readme.notzip", Error: ErrFormat},
|
Name: "symlink.zip",
|
||||||
|
File: []ZipTestFile{
|
||||||
|
{
|
||||||
|
Name: "symlink",
|
||||||
|
Content: []byte("../target"),
|
||||||
|
Mode: 0777 | os.ModeSymlink,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "readme.zip",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "readme.notzip",
|
||||||
|
Error: ErrFormat,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "dd.zip",
|
Name: "dd.zip",
|
||||||
File: []ZipTestFile{
|
File: []ZipTestFile{
|
||||||
|
@ -152,13 +152,20 @@ func (h *FileHeader) SetModTime(t time.Time) {
|
|||||||
h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
|
h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// traditional names for Unix constants
|
|
||||||
const (
|
const (
|
||||||
|
// Unix constants. The specification doesn't mention them,
|
||||||
|
// but these seem to be the values agreed on by tools.
|
||||||
s_IFMT = 0xf000
|
s_IFMT = 0xf000
|
||||||
s_IFDIR = 0x4000
|
s_IFSOCK = 0xc000
|
||||||
|
s_IFLNK = 0xa000
|
||||||
s_IFREG = 0x8000
|
s_IFREG = 0x8000
|
||||||
|
s_IFBLK = 0x6000
|
||||||
|
s_IFDIR = 0x4000
|
||||||
|
s_IFCHR = 0x2000
|
||||||
|
s_IFIFO = 0x1000
|
||||||
s_ISUID = 0x800
|
s_ISUID = 0x800
|
||||||
s_ISGID = 0x400
|
s_ISGID = 0x400
|
||||||
|
s_ISVTX = 0x200
|
||||||
|
|
||||||
msdosDir = 0x10
|
msdosDir = 0x10
|
||||||
msdosReadOnly = 0x01
|
msdosReadOnly = 0x01
|
||||||
@ -206,10 +213,23 @@ func msdosModeToFileMode(m uint32) (mode os.FileMode) {
|
|||||||
|
|
||||||
func fileModeToUnixMode(mode os.FileMode) uint32 {
|
func fileModeToUnixMode(mode os.FileMode) uint32 {
|
||||||
var m uint32
|
var m uint32
|
||||||
if mode&os.ModeDir != 0 {
|
switch mode & os.ModeType {
|
||||||
m = s_IFDIR
|
default:
|
||||||
} else {
|
|
||||||
m = s_IFREG
|
m = s_IFREG
|
||||||
|
case os.ModeDir:
|
||||||
|
m = s_IFDIR
|
||||||
|
case os.ModeSymlink:
|
||||||
|
m = s_IFLNK
|
||||||
|
case os.ModeNamedPipe:
|
||||||
|
m = s_IFIFO
|
||||||
|
case os.ModeSocket:
|
||||||
|
m = s_IFSOCK
|
||||||
|
case os.ModeDevice:
|
||||||
|
if mode&os.ModeCharDevice != 0 {
|
||||||
|
m = s_IFCHR
|
||||||
|
} else {
|
||||||
|
m = s_IFBLK
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if mode&os.ModeSetuid != 0 {
|
if mode&os.ModeSetuid != 0 {
|
||||||
m |= s_ISUID
|
m |= s_ISUID
|
||||||
@ -217,13 +237,29 @@ func fileModeToUnixMode(mode os.FileMode) uint32 {
|
|||||||
if mode&os.ModeSetgid != 0 {
|
if mode&os.ModeSetgid != 0 {
|
||||||
m |= s_ISGID
|
m |= s_ISGID
|
||||||
}
|
}
|
||||||
|
if mode&os.ModeSticky != 0 {
|
||||||
|
m |= s_ISVTX
|
||||||
|
}
|
||||||
return m | uint32(mode&0777)
|
return m | uint32(mode&0777)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unixModeToFileMode(m uint32) os.FileMode {
|
func unixModeToFileMode(m uint32) os.FileMode {
|
||||||
var mode os.FileMode
|
mode := os.FileMode(m & 0777)
|
||||||
if m&s_IFMT == s_IFDIR {
|
switch m & s_IFMT {
|
||||||
|
case s_IFBLK:
|
||||||
|
mode |= os.ModeDevice
|
||||||
|
case s_IFCHR:
|
||||||
|
mode |= os.ModeDevice | os.ModeCharDevice
|
||||||
|
case s_IFDIR:
|
||||||
mode |= os.ModeDir
|
mode |= os.ModeDir
|
||||||
|
case s_IFIFO:
|
||||||
|
mode |= os.ModeNamedPipe
|
||||||
|
case s_IFLNK:
|
||||||
|
mode |= os.ModeSymlink
|
||||||
|
case s_IFREG:
|
||||||
|
// nothing to do
|
||||||
|
case s_IFSOCK:
|
||||||
|
mode |= os.ModeSocket
|
||||||
}
|
}
|
||||||
if m&s_ISGID != 0 {
|
if m&s_ISGID != 0 {
|
||||||
mode |= os.ModeSetgid
|
mode |= os.ModeSetgid
|
||||||
@ -231,5 +267,8 @@ func unixModeToFileMode(m uint32) os.FileMode {
|
|||||||
if m&s_ISUID != 0 {
|
if m&s_ISUID != 0 {
|
||||||
mode |= os.ModeSetuid
|
mode |= os.ModeSetuid
|
||||||
}
|
}
|
||||||
return mode | os.FileMode(m&0777)
|
if m&s_ISVTX != 0 {
|
||||||
|
mode |= os.ModeSticky
|
||||||
|
}
|
||||||
|
return mode
|
||||||
}
|
}
|
||||||
|
BIN
src/pkg/archive/zip/testdata/symlink.zip
vendored
Normal file
BIN
src/pkg/archive/zip/testdata/symlink.zip
vendored
Normal file
Binary file not shown.
@ -47,10 +47,10 @@ var writeTests = []WriteTest{
|
|||||||
Mode: 0755 | os.ModeSetgid,
|
Mode: 0755 | os.ModeSetgid,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "setgid",
|
Name: "symlink",
|
||||||
Data: []byte("setgid file"),
|
Data: []byte("../link/target"),
|
||||||
Method: Deflate,
|
Method: Deflate,
|
||||||
Mode: 0755 | os.ModeSetgid,
|
Mode: 0755 | os.ModeSymlink,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user