mirror of https://github.com/golang/go.git
compress/gzip: return unexpected EOF for certain truncated streams
For cases where RFC 1952 requires a field, the code returns the error io.ErrUnexpectedEOF except in two places: for the FNAME flag or the FCOMMENT flag. These flags expect a null-terminated string and readString() may return an EOF if the Reader is truncated before a null byte is found. For consistency with parsing other parts of the header, this is converted to an unexpected EOF herein. * Fixes #51417 see https://go-review.googlesource.com/c/go/+/14832/
This commit is contained in:
parent
d40e7bb174
commit
2e573cd961
|
|
@ -211,14 +211,14 @@ func (z *Reader) readHeader() (hdr Header, err error) {
|
|||
var s string
|
||||
if flg&flagName != 0 {
|
||||
if s, err = z.readString(); err != nil {
|
||||
return hdr, err
|
||||
return hdr, noEOF(err)
|
||||
}
|
||||
hdr.Name = s
|
||||
}
|
||||
|
||||
if flg&flagComment != 0 {
|
||||
if s, err = z.readString(); err != nil {
|
||||
return hdr, err
|
||||
return hdr, noEOF(err)
|
||||
}
|
||||
hdr.Comment = s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,6 +359,38 @@ var gunzipTests = []gunzipTest{
|
|||
},
|
||||
io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
"hello.txt",
|
||||
"gzip header with truncated name",
|
||||
"hello world\n",
|
||||
[]byte{
|
||||
0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
|
||||
0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
|
||||
0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
|
||||
0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
|
||||
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
||||
0x00, 0x00,
|
||||
0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0x01,
|
||||
},
|
||||
io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
"",
|
||||
"gzip header with truncated comment",
|
||||
"hello world\n",
|
||||
[]byte{
|
||||
0x1f, 0x8b, 0x08, 0x10, 0xc8, 0x58, 0x13, 0x4a,
|
||||
0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
|
||||
0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
|
||||
0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
|
||||
0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
|
||||
0x00, 0x00,
|
||||
0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0x01,
|
||||
},
|
||||
io.ErrUnexpectedEOF,
|
||||
},
|
||||
}
|
||||
|
||||
func TestDecompressor(t *testing.T) {
|
||||
|
|
@ -495,23 +527,45 @@ func TestNilStream(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTruncatedStreams(t *testing.T) {
|
||||
const data = "\x1f\x8b\b\x04\x00\tn\x88\x00\xff\a\x00foo bar\xcbH\xcd\xc9\xc9\xd7Q(\xcf/\xcaI\x01\x04:r\xab\xff\f\x00\x00\x00"
|
||||
cases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
}{
|
||||
{
|
||||
name: "original",
|
||||
data: []byte("\x1f\x8b\b\x04\x00\tn\x88\x00\xff\a\x00foo bar\xcbH\xcd\xc9\xc9\xd7Q(\xcf/\xcaI\x01\x04:r\xab\xff\f\x00\x00\x00"),
|
||||
},
|
||||
{
|
||||
name: "truncated name",
|
||||
data: []byte{
|
||||
0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "truncated comment",
|
||||
data: []byte{
|
||||
0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Intentionally iterate starting with at least one byte in the stream.
|
||||
for i := 1; i < len(data)-1; i++ {
|
||||
r, err := NewReader(strings.NewReader(data[:i]))
|
||||
if err != nil {
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("NewReader(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF)
|
||||
for _, tc := range cases {
|
||||
for i := 1; i < len(tc.data); i++ {
|
||||
r, err := NewReader(strings.NewReader(string(tc.data[:i])))
|
||||
if err != nil {
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("NewReader(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
|
||||
}
|
||||
continue
|
||||
}
|
||||
_, err = io.Copy(io.Discard, r)
|
||||
if ferr, ok := err.(*flate.ReadError); ok {
|
||||
err = ferr.Err
|
||||
}
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("io.Copy(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
|
||||
}
|
||||
continue
|
||||
}
|
||||
_, err = io.Copy(io.Discard, r)
|
||||
if ferr, ok := err.(*flate.ReadError); ok {
|
||||
err = ferr.Err
|
||||
}
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("io.Copy(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue