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:
parent
df8572a1eb
commit
e46a815cbc
1 changed files with 22 additions and 6 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue