const (
// Type '0' indicates a regular file.
TypeReg = '0'
- TypeRegA = '\x00' // For legacy support; use TypeReg instead
+ TypeRegA = '\x00' // Deprecated: Use TypeReg instead.
// Type '1' to '6' are header-only flags and may not have a data body.
TypeLink = '1' // Hard link
// should do so by creating a new Header and copying the fields
// that they are interested in preserving.
type Header struct {
- Typeflag byte // Type of header entry (should be TypeReg for most files)
+ // Typeflag is the type of header entry.
+ // The zero value is automatically promoted to either TypeReg or TypeDir
+ // depending on the presence of a trailing slash in Name.
+ Typeflag byte
Name string // Name of file entry
Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
if gnuLongLink != "" {
hdr.Linkname = gnuLongLink
}
- if hdr.Typeflag == TypeRegA && strings.HasSuffix(hdr.Name, "/") {
- hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
+ if hdr.Typeflag == TypeRegA {
+ if strings.HasSuffix(hdr.Name, "/") {
+ hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
+ } else {
+ hdr.Typeflag = TypeReg
+ }
}
// The extended headers may have updated the size.
Gid: 5000,
Size: 5,
ModTime: time.Unix(1244593104, 0),
- Typeflag: '\x00',
+ Typeflag: '0',
}, {
Name: "small2.txt",
Mode: 0444,
Gid: 5000,
Size: 11,
ModTime: time.Unix(1244593104, 0),
- Typeflag: '\x00',
+ Typeflag: '0',
}},
}, {
file: "testdata/pax.tar",
// a buggy pre-Go1.8 tar.Writer.
file: "testdata/invalid-go17.tar",
headers: []*Header{{
- Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
- Uid: 010000000,
- ModTime: time.Unix(0, 0),
+ Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
+ Uid: 010000000,
+ ModTime: time.Unix(0, 0),
+ Typeflag: '0',
}},
}, {
// USTAR archive with a regular entry with non-zero device numbers.
ModTime: time.Now().Round(time.Second),
PAXRecords: map[string]string{"uid": "2097152"},
Format: FormatPAX,
+ Typeflag: TypeReg,
}
if err := tw.WriteHeader(hdr); err != nil {
t.Fatalf("tw.WriteHeader: %v", err)
}
tw.hdr = *hdr // Shallow copy of Header
+ // Avoid usage of the legacy TypeRegA flag, and automatically promote
+ // it to use TypeReg or TypeDir.
+ if tw.hdr.Typeflag == TypeRegA {
+ if strings.HasSuffix(tw.hdr.Name, "/") {
+ tw.hdr.Typeflag = TypeDir
+ } else {
+ tw.hdr.Typeflag = TypeReg
+ }
+ }
+
// Round ModTime and ignore AccessTime and ChangeTime unless
// the format is explicitly chosen.
// This ensures nominal usage of WriteHeader (without specifying the format)
testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
testClose{nil},
},
+ }, {
+ // Automatically promote zero value of Typeflag depending on the name.
+ file: "testdata/file-and-dir.tar",
+ tests: []testFnc{
+ testHeader{Header{Name: "small.txt", Size: 5}, nil},
+ testWrite{"Kilts", 5, nil},
+ testHeader{Header{Name: "dir/"}, nil},
+ testClose{nil},
+ },
}}
equalError := func(x, y error) bool {
if err != nil {
t.Fatalf("Failed to read header: %s", err)
}
- if header.Typeflag != 0 {
- t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag)
+ if header.Typeflag != TypeReg {
+ t.Fatalf("Typeflag should've been %d, found %d", TypeReg, header.Typeflag)
}
}
}