Skip to content

Commit

Permalink
archive/tar: remove file type bits from mode field
Browse files Browse the repository at this point in the history
When writing tar files by using the FileInfoHeader
the type bits was set in the mode field of the header
This is not correct according to the standard (GNU/Posix) and
other implementations.

Fixed #20150

Change-Id: I3be7d946a1923ad5827cf45c696546a5e287ebba
Reviewed-on: https://go-review.googlesource.com/42093
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
Lars Jeppesen authored and dsnet committed May 13, 2017
1 parent 8f06e21 commit 66b5a2f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
20 changes: 9 additions & 11 deletions src/archive/tar/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,15 @@ func (fi headerFileInfo) Mode() (mode os.FileMode) {
// sysStat, if non-nil, populates h from system-dependent fields of fi.
var sysStat func(fi os.FileInfo, h *Header) error

// Mode constants from the tar spec.
const (
c_ISUID = 04000 // Set uid
c_ISGID = 02000 // Set gid
c_ISVTX = 01000 // Save text (sticky bit)
// Mode constants from the USTAR spec:
// See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06
c_ISUID = 04000 // Set uid
c_ISGID = 02000 // Set gid
c_ISVTX = 01000 // Save text (sticky bit)

// Common Unix mode constants; these are not defined in any common tar standard.
// Header.FileInfo understands these, but FileInfoHeader will never produce these.
c_ISDIR = 040000 // Directory
c_ISFIFO = 010000 // FIFO
c_ISREG = 0100000 // Regular file
Expand Down Expand Up @@ -208,30 +212,24 @@ func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
}
switch {
case fm.IsRegular():
h.Mode |= c_ISREG
h.Typeflag = TypeReg
h.Size = fi.Size()
case fi.IsDir():
h.Typeflag = TypeDir
h.Mode |= c_ISDIR
h.Name += "/"
case fm&os.ModeSymlink != 0:
h.Typeflag = TypeSymlink
h.Mode |= c_ISLNK
h.Linkname = link
case fm&os.ModeDevice != 0:
if fm&os.ModeCharDevice != 0 {
h.Mode |= c_ISCHR
h.Typeflag = TypeChar
} else {
h.Mode |= c_ISBLK
h.Typeflag = TypeBlock
}
case fm&os.ModeNamedPipe != 0:
h.Typeflag = TypeFifo
h.Mode |= c_ISFIFO
case fm&os.ModeSocket != 0:
h.Mode |= c_ISSOCK
return nil, fmt.Errorf("archive/tar: sockets not supported")
default:
return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm)
}
Expand Down
26 changes: 13 additions & 13 deletions src/archive/tar/tar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestFileInfoHeader(t *testing.T) {
if g, e := h.Name, "small.txt"; g != e {
t.Errorf("Name = %q; want %q", g, e)
}
if g, e := h.Mode, int64(fi.Mode().Perm())|c_ISREG; g != e {
if g, e := h.Mode, int64(fi.Mode().Perm()); g != e {
t.Errorf("Mode = %#o; want %#o", g, e)
}
if g, e := h.Size, int64(5); g != e {
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestFileInfoHeaderDir(t *testing.T) {
t.Errorf("Name = %q; want %q", g, e)
}
// Ignoring c_ISGID for golang.org/issue/4867
if g, e := h.Mode&^c_ISGID, int64(fi.Mode().Perm())|c_ISDIR; g != e {
if g, e := h.Mode&^c_ISGID, int64(fi.Mode().Perm()); g != e {
t.Errorf("Mode = %#o; want %#o", g, e)
}
if g, e := h.Size, int64(0); g != e {
Expand Down Expand Up @@ -157,7 +157,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// regular file.
h: &Header{
Name: "test.txt",
Mode: 0644 | c_ISREG,
Mode: 0644,
Size: 12,
ModTime: time.Unix(1360600916, 0),
Typeflag: TypeReg,
Expand All @@ -167,7 +167,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// symbolic link.
h: &Header{
Name: "link.txt",
Mode: 0777 | c_ISLNK,
Mode: 0777,
Size: 0,
ModTime: time.Unix(1360600852, 0),
Typeflag: TypeSymlink,
Expand All @@ -177,7 +177,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// character device node.
h: &Header{
Name: "dev/null",
Mode: 0666 | c_ISCHR,
Mode: 0666,
Size: 0,
ModTime: time.Unix(1360578951, 0),
Typeflag: TypeChar,
Expand All @@ -187,7 +187,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// block device node.
h: &Header{
Name: "dev/sda",
Mode: 0660 | c_ISBLK,
Mode: 0660,
Size: 0,
ModTime: time.Unix(1360578954, 0),
Typeflag: TypeBlock,
Expand All @@ -197,7 +197,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// directory.
h: &Header{
Name: "dir/",
Mode: 0755 | c_ISDIR,
Mode: 0755,
Size: 0,
ModTime: time.Unix(1360601116, 0),
Typeflag: TypeDir,
Expand All @@ -207,7 +207,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// fifo node.
h: &Header{
Name: "dev/initctl",
Mode: 0600 | c_ISFIFO,
Mode: 0600,
Size: 0,
ModTime: time.Unix(1360578949, 0),
Typeflag: TypeFifo,
Expand All @@ -217,7 +217,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// setuid.
h: &Header{
Name: "bin/su",
Mode: 0755 | c_ISREG | c_ISUID,
Mode: 0755 | c_ISUID,
Size: 23232,
ModTime: time.Unix(1355405093, 0),
Typeflag: TypeReg,
Expand All @@ -227,7 +227,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// setguid.
h: &Header{
Name: "group.txt",
Mode: 0750 | c_ISREG | c_ISGID,
Mode: 0750 | c_ISGID,
Size: 0,
ModTime: time.Unix(1360602346, 0),
Typeflag: TypeReg,
Expand All @@ -237,7 +237,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// sticky.
h: &Header{
Name: "sticky.txt",
Mode: 0600 | c_ISREG | c_ISVTX,
Mode: 0600 | c_ISVTX,
Size: 7,
ModTime: time.Unix(1360602540, 0),
Typeflag: TypeReg,
Expand All @@ -247,7 +247,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// hard link.
h: &Header{
Name: "hard.txt",
Mode: 0644 | c_ISREG,
Mode: 0644,
Size: 0,
Linkname: "file.txt",
ModTime: time.Unix(1360600916, 0),
Expand All @@ -258,7 +258,7 @@ func TestHeaderRoundTrip(t *testing.T) {
// More information.
h: &Header{
Name: "info.txt",
Mode: 0600 | c_ISREG,
Mode: 0600,
Size: 0,
Uid: 1000,
Gid: 1000,
Expand Down

0 comments on commit 66b5a2f

Please sign in to comment.