mirror of
https://github.com/golang/go
synced 2024-11-25 00:07:56 -07:00
archive/tar: catch short writes.
Also make error messages consistent throughout. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/5777064
This commit is contained in:
parent
ac0789c63e
commit
d75abb7ca3
@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrHeader = errors.New("invalid tar header")
|
ErrHeader = errors.New("archive/tar: invalid tar header")
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Reader provides sequential access to the contents of a tar archive.
|
// A Reader provides sequential access to the contents of a tar archive.
|
||||||
|
@ -5,18 +5,19 @@
|
|||||||
package tar
|
package tar
|
||||||
|
|
||||||
// TODO(dsymonds):
|
// TODO(dsymonds):
|
||||||
// - catch more errors (no first header, write after close, etc.)
|
// - catch more errors (no first header, etc.)
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrWriteTooLong = errors.New("write too long")
|
ErrWriteTooLong = errors.New("archive/tar: write too long")
|
||||||
ErrFieldTooLong = errors.New("header field too long")
|
ErrFieldTooLong = errors.New("archive/tar: header field too long")
|
||||||
ErrWriteAfterClose = errors.New("write after close")
|
ErrWriteAfterClose = errors.New("archive/tar: write after close")
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Writer provides sequential writing of a tar archive in POSIX.1 format.
|
// A Writer provides sequential writing of a tar archive in POSIX.1 format.
|
||||||
@ -48,6 +49,11 @@ func NewWriter(w io.Writer) *Writer { return &Writer{w: w} }
|
|||||||
|
|
||||||
// Flush finishes writing the current file (optional).
|
// Flush finishes writing the current file (optional).
|
||||||
func (tw *Writer) Flush() error {
|
func (tw *Writer) Flush() error {
|
||||||
|
if tw.nb > 0 {
|
||||||
|
tw.err = fmt.Errorf("archive/tar: missed writing %d bytes", tw.nb)
|
||||||
|
return tw.err
|
||||||
|
}
|
||||||
|
|
||||||
n := tw.nb + tw.pad
|
n := tw.nb + tw.pad
|
||||||
for n > 0 && tw.err == nil {
|
for n > 0 && tw.err == nil {
|
||||||
nr := n
|
nr := n
|
||||||
@ -193,6 +199,9 @@ func (tw *Writer) Close() error {
|
|||||||
}
|
}
|
||||||
tw.Flush()
|
tw.Flush()
|
||||||
tw.closed = true
|
tw.closed = true
|
||||||
|
if tw.err != nil {
|
||||||
|
return tw.err
|
||||||
|
}
|
||||||
|
|
||||||
// trailer: two zero blocks
|
// trailer: two zero blocks
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"testing/iotest"
|
"testing/iotest"
|
||||||
"time"
|
"time"
|
||||||
@ -95,7 +96,8 @@ var writerTests = []*writerTest{
|
|||||||
Uname: "dsymonds",
|
Uname: "dsymonds",
|
||||||
Gname: "eng",
|
Gname: "eng",
|
||||||
},
|
},
|
||||||
// no contents
|
// fake contents
|
||||||
|
contents: strings.Repeat("\x00", 4<<10),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -150,7 +152,9 @@ testLoop:
|
|||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
|
tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
|
||||||
|
big := false
|
||||||
for j, entry := range test.entries {
|
for j, entry := range test.entries {
|
||||||
|
big = big || entry.header.Size > 1<<10
|
||||||
if err := tw.WriteHeader(entry.header); err != nil {
|
if err := tw.WriteHeader(entry.header); err != nil {
|
||||||
t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
|
t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
|
||||||
continue testLoop
|
continue testLoop
|
||||||
@ -160,7 +164,8 @@ testLoop:
|
|||||||
continue testLoop
|
continue testLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := tw.Close(); err != nil {
|
// Only interested in Close failures for the small tests.
|
||||||
|
if err := tw.Close(); err != nil && !big {
|
||||||
t.Errorf("test %d: Failed closing archive: %v", i, err)
|
t.Errorf("test %d: Failed closing archive: %v", i, err)
|
||||||
continue testLoop
|
continue testLoop
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user