diff --git a/binary/binary.go b/binary/binary.go index a613767e7..962eef98c 100644 --- a/binary/binary.go +++ b/binary/binary.go @@ -10,7 +10,8 @@ import ( // TODO document and maybe make it configurable. const MaxBinaryReadSize = 21 * 1024 * 1024 -var ErrMaxBinaryReadSizeReached = errors.New("Error: max binary read size reached") +var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow") +var ErrBinaryReadSizeUnderflow = errors.New("Error: binary read size underflow") func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) diff --git a/binary/byteslice.go b/binary/byteslice.go index c8b8cb2a5..b7a7550a8 100644 --- a/binary/byteslice.go +++ b/binary/byteslice.go @@ -2,6 +2,8 @@ package binary import ( "io" + + . "github.com/tendermint/tendermint/common" ) func WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error) { @@ -14,8 +16,12 @@ func ReadByteSlice(r io.Reader, n *int64, err *error) []byte { if *err != nil { return nil } - if MaxBinaryReadSize < *n+int64(length) { - *err = ErrMaxBinaryReadSizeReached + if length < 0 { + *err = ErrBinaryReadSizeUnderflow + return nil + } + if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + *err = ErrBinaryReadSizeOverflow return nil } @@ -41,8 +47,12 @@ func ReadByteSlices(r io.Reader, n *int64, err *error) [][]byte { if *err != nil { return nil } - if MaxBinaryReadSize < *n+int64(length) { - *err = ErrMaxBinaryReadSizeReached + if length < 0 { + *err = ErrBinaryReadSizeUnderflow + return nil + } + if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + *err = ErrBinaryReadSizeOverflow return nil } diff --git a/binary/reflect.go b/binary/reflect.go index 55e60d239..3aea034e3 100644 --- a/binary/reflect.go +++ b/binary/reflect.go @@ -274,7 +274,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea return } if MaxBinaryReadSize < *n { - *err = ErrMaxBinaryReadSizeReached + *err = ErrBinaryReadSizeOverflow return } } diff --git a/binary/reflect_test.go b/binary/reflect_test.go index 8d1b03861..e24e3540d 100644 --- a/binary/reflect_test.go +++ b/binary/reflect_test.go @@ -456,7 +456,7 @@ func TestJSONFieldNames(t *testing.T) { func TestBadAlloc(t *testing.T) { n, err := new(int64), new(error) instance := new([]byte) - data := RandBytes(ByteSliceChunk * 100) + data := RandBytes(100 * 1024) b := new(bytes.Buffer) // this slice of data claims to be much bigger than it really is WriteUvarint(uint(10000000000000000), b, n, err) diff --git a/binary/string.go b/binary/string.go index d05744b04..f08633a04 100644 --- a/binary/string.go +++ b/binary/string.go @@ -1,6 +1,10 @@ package binary -import "io" +import ( + "io" + + . "github.com/tendermint/tendermint/common" +) // String @@ -14,8 +18,12 @@ func ReadString(r io.Reader, n *int64, err *error) string { if *err != nil { return "" } - if MaxBinaryReadSize < *n+int64(length) { - *err = ErrMaxBinaryReadSizeReached + if length < 0 { + *err = ErrBinaryReadSizeUnderflow + return "" + } + if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + *err = ErrBinaryReadSizeOverflow return "" } diff --git a/merkle/iavl_proof.go b/merkle/iavl_proof.go index 4d1b11ab9..0541aa738 100644 --- a/merkle/iavl_proof.go +++ b/merkle/iavl_proof.go @@ -3,7 +3,6 @@ package merkle import ( "bytes" "crypto/sha256" - "github.com/tendermint/tendermint/binary" . "github.com/tendermint/tendermint/common" ) @@ -47,7 +46,7 @@ func (branch IAVLProofInnerNode) Hash(childHash []byte) []byte { n, err := int64(0), error(nil) binary.WriteInt8(branch.Height, buf, &n, &err) binary.WriteVarint(branch.Size, buf, &n, &err) - if branch.Left == nil { + if len(branch.Left) == 0 { binary.WriteByteSlice(childHash, buf, &n, &err) binary.WriteByteSlice(branch.Right, buf, &n, &err) } else { diff --git a/merkle/iavl_test.go b/merkle/iavl_test.go index ae3747736..b0f5d9bf9 100644 --- a/merkle/iavl_test.go +++ b/merkle/iavl_test.go @@ -253,6 +253,7 @@ func testProof(t *testing.T, proof *IAVLProof, keyBytes, valueBytes, rootHash [] return } if !proof2.Verify(keyBytes, valueBytes, rootHash) { + // t.Log(Fmt("%X\n%X\n", proofBytes, binary.BinaryBytes(proof2))) t.Errorf("Invalid proof after write/read. Verification failed.") return } diff --git a/p2p/connection.go b/p2p/connection.go index a8021c777..c08956035 100644 --- a/p2p/connection.go +++ b/p2p/connection.go @@ -579,7 +579,7 @@ func (ch *Channel) writeMsgPacketTo(w io.Writer) (n int64, err error) { func (ch *Channel) recvMsgPacket(packet msgPacket) ([]byte, error) { log.Debug("Read Msg Packet", "conn", ch.conn, "packet", packet) if binary.MaxBinaryReadSize < len(ch.recving)+len(packet.Bytes) { - return nil, binary.ErrMaxBinaryReadSizeReached + return nil, binary.ErrBinaryReadSizeOverflow } ch.recving = append(ch.recving, packet.Bytes...) if packet.EOF == byte(0x01) { diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 000000000..186241178 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1 @@ +* http://redsymbol.net/articles/unofficial-bash-strict-mode/