Skip to content

Commit

Permalink
Avoid panics on invalid input
Browse files Browse the repository at this point in the history
This PR prevents code from panicking and fixes some small errors
during unpacking:

Prevents malformed input for composite lists to cause the pogs
library to panic.

Make the `packed.Decoder` throw an error if the input is `0x00`.
According to the spec, at least one more byte is required.

Make the `packet.Decoder` throw an error if the input for the
unpacked bytes (`0xFF` tag) does not contain enough unpacked bytes.

fixes capnproto#137
  • Loading branch information
oncilla committed May 5, 2019
1 parent e1ae1f9 commit 12bdc40
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
11 changes: 9 additions & 2 deletions capn.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) {
}
sz := hdr.structSize()
n := int32(hdr.offset())
if n < 0 {
return List{}, errListSize
}
// TODO(light): check that this has the same end address
if tsize, ok := sz.totalSize().times(n); !ok {
return List{}, errOverflow
Expand All @@ -214,19 +217,23 @@ func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) {
flags: isCompositeList,
}, nil
}
n := val.numListElements()
if n < 0 {
return List{}, errListSize
}
if lt == bit1List {
return List{
seg: s,
off: addr,
length: val.numListElements(),
length: n,
flags: isBitList,
}, nil
}
return List{
seg: s,
size: val.elementSize(),
off: addr,
length: val.numListElements(),
length: n,
}, nil
}

Expand Down
23 changes: 13 additions & 10 deletions internal/packed/packed.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ func Unpack(dst, src []byte) ([]byte, error) {
dst = allocWords(dst, int(src[0]))
src = src[1:]
n := copy(dst[start:], src)
if n < len(dst)-start {
return dst, io.ErrUnexpectedEOF
}
src = src[n:]
}
}
Expand Down Expand Up @@ -281,22 +284,22 @@ func (r *Reader) ReadWord(p []byte) error {
switch tag {
case zeroTag:
z, err := r.rd.ReadByte()
if err == io.EOF {
r.err = io.ErrUnexpectedEOF
return nil
} else if err != nil {
if err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
r.err = err
return nil
return err
}
r.zeroes = int(z)
case unpackedTag:
l, err := r.rd.ReadByte()
if err == io.EOF {
r.err = io.ErrUnexpectedEOF
return nil
} else if err != nil {
if err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
r.err = err
return nil
return err
}
r.literal = int(l)
}
Expand Down
21 changes: 21 additions & 0 deletions internal/packed/packed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,27 @@ var badDecompressionTests = []struct {
name string
input []byte
}{
{
"short zero tag",
[]byte{0x00},
},
{
"short unpacked tag",
[]byte{0xFF},
},
{
"unpacked tag, only one word",
[]byte{
0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
},
},
{
"unpacked tag, short unpacked word",
[]byte{
0xFF, 0, 0, 0, 0, 0, 0, 0, 0,
0x01, 0,
},
},
{
"wrong tag",
[]byte{
Expand Down

0 comments on commit 12bdc40

Please sign in to comment.