if f.err != nil {
return f.err // Should never happen since header is validated
}
- return tw.writeRawHeader(blk, hdr.Size)
+ return tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag)
}
func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
if f.err != nil && len(paxHdrs) == 0 {
return f.err // Should never happen, otherwise PAX headers would be used
}
- return tw.writeRawHeader(blk, hdr.Size)
+ return tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag)
}
func (tw *Writer) writeGNUHeader(hdr *Header) error {
if f.err != nil {
return f.err // Should never happen since header is validated
}
- return tw.writeRawHeader(blk, hdr.Size)
+ return tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag)
}
type (
}
// Write the header and data.
- if err := tw.writeRawHeader(&tw.blk, int64(len(data))); err != nil {
+ if err := tw.writeRawHeader(&tw.blk, int64(len(data)), flag); err != nil {
return err
}
_, err := io.WriteString(tw, data)
// writeRawHeader writes the value of blk, regardless of its value.
// It sets up the Writer such that it can accept a file of the given size.
-func (tw *Writer) writeRawHeader(blk *block, size int64) error {
+// If the flag is a special header-only flag, then the size is treated as zero.
+func (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error {
if err := tw.Flush(); err != nil {
return err
}
if _, err := tw.w.Write(blk[:]); err != nil {
return err
}
- // TODO(dsnet): Set Size implicitly to zero for header-only entries.
- // See https://golang.org/issue/15565
+ if isHeaderOnlyType(flag) {
+ size = 0
+ }
tw.nb = size
tw.pad = -size & (blockSize - 1) // blockSize is a power of two
return nil
}
}
+func TestWriteHeaderOnly(t *testing.T) {
+ tw := NewWriter(new(bytes.Buffer))
+ hdr := &Header{Name: "dir/", Typeflag: TypeDir}
+ if err := tw.WriteHeader(hdr); err != nil {
+ t.Fatalf("WriteHeader() = %v, want nil", err)
+ }
+ if _, err := tw.Write([]byte{0x00}); err != ErrWriteTooLong {
+ t.Fatalf("Write() = %v, want %v", err, ErrWriteTooLong)
+ }
+}
+
+func TestWriteNegativeSize(t *testing.T) {
+ tw := NewWriter(new(bytes.Buffer))
+ hdr := &Header{Name: "small.txt", Size: -1}
+ if err := tw.WriteHeader(hdr); err != ErrHeader {
+ t.Fatalf("WriteHeader() = nil, want %v", ErrHeader)
+ }
+}
+
func TestWriteAfterClose(t *testing.T) {
var buffer bytes.Buffer
tw := NewWriter(&buffer)