1
0
Fork 0
forked from mirrors/tar-split

archive/tar: fix carry-over of bytes for GNU types

Archives produced with GNU tar can have types of TypeGNULongName and
TypeGNULongLink.
These fields effectively appear like two file entries in the tar
archive. While golang's `archive/tar` transparently provide the file
name and headers and file payload, the access to the raw bytes is still
needed.

This fixes the access to the longlink header, it's payload (of the long
file path name), and the following file header and actual file payload.
This commit is contained in:
Vincent Batts 2015-08-11 15:51:52 -04:00
parent df8572a1eb
commit e46a815cbc

View file

@ -154,44 +154,60 @@ func (tr *Reader) Next() (*Header, error) {
} }
return hdr, nil return hdr, nil
case TypeGNULongName: case TypeGNULongName:
var b *bytes.Buffer
if tr.RawAccounting {
b = bytes.NewBuffer(tr.RawBytes())
}
// We have a GNU long name header. Its contents are the real file name. // We have a GNU long name header. Its contents are the real file name.
realname, err := ioutil.ReadAll(tr) realname, err := ioutil.ReadAll(tr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var b []byte
if tr.RawAccounting { if tr.RawAccounting {
if _, err = tr.rawBytes.Write(b.Bytes()); err != nil {
return nil, err
}
if _, err = tr.rawBytes.Write(realname); err != nil { if _, err = tr.rawBytes.Write(realname); err != nil {
return nil, err return nil, err
} }
b = tr.RawBytes() b.Reset()
b.Write(tr.RawBytes())
} }
hdr, err := tr.Next() hdr, err := tr.Next()
// since the above call to Next() resets the buffer, we need to throw the bytes over // since the above call to Next() resets the buffer, we need to throw the bytes over
if tr.RawAccounting { if tr.RawAccounting {
if _, err = tr.rawBytes.Write(b); err != nil { b.Write(tr.RawBytes())
if _, err = tr.rawBytes.Write(b.Bytes()); err != nil {
return nil, err return nil, err
} }
} }
hdr.Name = cString(realname) hdr.Name = cString(realname)
return hdr, err return hdr, err
case TypeGNULongLink: case TypeGNULongLink:
var b *bytes.Buffer
if tr.RawAccounting {
b = bytes.NewBuffer(tr.RawBytes())
}
// We have a GNU long link header. // We have a GNU long link header.
realname, err := ioutil.ReadAll(tr) realname, err := ioutil.ReadAll(tr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var b []byte
if tr.RawAccounting { if tr.RawAccounting {
if _, err = tr.rawBytes.Write(b.Bytes()); err != nil {
return nil, err
}
if _, err = tr.rawBytes.Write(realname); err != nil { if _, err = tr.rawBytes.Write(realname); err != nil {
return nil, err return nil, err
} }
b = tr.RawBytes() b.Reset()
b.Write(tr.RawBytes())
} }
hdr, err := tr.Next() hdr, err := tr.Next()
// since the above call to Next() resets the buffer, we need to throw the bytes over // since the above call to Next() resets the buffer, we need to throw the bytes over
if tr.RawAccounting { if tr.RawAccounting {
if _, err = tr.rawBytes.Write(b); err != nil { b.Write(tr.RawBytes())
if _, err = tr.rawBytes.Write(b.Bytes()); err != nil {
return nil, err return nil, err
} }
} }