Commit 115ce5fb authored by Levin Zimmermann's avatar Levin Zimmermann

go/proto/msgpack: Simplify debugging by printing function name in case of overflow

parent b59f0b04
...@@ -44,7 +44,7 @@ func (e *mstructDecodeError) Error() string { ...@@ -44,7 +44,7 @@ func (e *mstructDecodeError) Error() string {
// mdecodeErr is called to normilize error when msgp.ReadXXX returns err when decoding path. // mdecodeErr is called to normilize error when msgp.ReadXXX returns err when decoding path.
func mdecodeErr(path string, err error) error { func mdecodeErr(path string, err error) error {
if err == msgp.ErrShortBytes { if err == msgp.ErrShortBytes {
return ErrDecodeOverflow return &ErrDecodeOverflow{path}
} }
return &mdecodeError{path, err} return &mdecodeError{path, err}
} }
......
...@@ -228,3 +228,12 @@ func (addr Address) String() string { ...@@ -228,3 +228,12 @@ func (addr Address) String() string {
return net.JoinHostPort(addr.Host, fmt.Sprintf("%d", addr.Port)) return net.JoinHostPort(addr.Host, fmt.Sprintf("%d", addr.Port))
} }
} }
// ErrDecodeOverflow is the error returned by neoMsgDecode when decoding hits buffer overflow
type ErrDecodeOverflow struct {
function string
}
func (e *ErrDecodeOverflow) Error() string {
return fmt.Sprintf("decode '%s': buffer overflow", e.function)
}
...@@ -70,7 +70,6 @@ import ( ...@@ -70,7 +70,6 @@ import (
"lab.nexedi.com/kirr/neo/go/internal/packed" "lab.nexedi.com/kirr/neo/go/internal/packed"
"encoding/binary" "encoding/binary"
"errors"
"math" "math"
) )
...@@ -168,9 +167,6 @@ func (e Encoding) MsgDecode(msg Msg, data []byte) (nread int, err error) { ...@@ -168,9 +167,6 @@ func (e Encoding) MsgDecode(msg Msg, data []byte) (nread int, err error) {
} }
// ErrDecodeOverflow is the error returned by neoMsgDecode when decoding hits buffer overflow
var ErrDecodeOverflow = errors.New("decode: buffer overflow")
// ---- messages ---- // ---- messages ----
//neo:proto enum //neo:proto enum
......
...@@ -22,6 +22,7 @@ package proto ...@@ -22,6 +22,7 @@ package proto
import ( import (
"encoding/binary" "encoding/binary"
"errors"
hexpkg "encoding/hex" hexpkg "encoding/hex"
"fmt" "fmt"
"reflect" "reflect"
...@@ -152,7 +153,8 @@ func testMsgMarshal(t *testing.T, enc Encoding, msg Msg, encoded string) { ...@@ -152,7 +153,8 @@ func testMsgMarshal(t *testing.T, enc Encoding, msg Msg, encoded string) {
// decode must detect buffer overflow // decode must detect buffer overflow
for l := len(encoded) - 1; l >= 0; l-- { for l := len(encoded) - 1; l >= 0; l-- {
n, err = enc.MsgDecode(msg2, data[:l]) n, err = enc.MsgDecode(msg2, data[:l])
if !(n == 0 && err == ErrDecodeOverflow) { errDecodeOverflow := new(ErrDecodeOverflow)
if !(n == 0 && errors.As(err, &errDecodeOverflow)) {
t.Errorf("%c/%v: decode overflow not detected on [:%v]", enc, typ, l) t.Errorf("%c/%v: decode overflow not detected on [:%v]", enc, typ, l)
} }
...@@ -429,9 +431,10 @@ func TestMsgDecodeLenOverflowN(t *testing.T) { ...@@ -429,9 +431,10 @@ func TestMsgDecodeLenOverflowN(t *testing.T) {
}() }()
n, err := enc.MsgDecode(tt.msg, data) n, err := enc.MsgDecode(tt.msg, data)
if !(n == 0 && err == ErrDecodeOverflow) { errDecodeOverflow := new(ErrDecodeOverflow)
if !(n == 0 && errors.As(err, &errDecodeOverflow)) {
t.Errorf("%T: decode %x\nhave: %d, %v\nwant: %d, %v", tt.msg, data, t.Errorf("%T: decode %x\nhave: %d, %v\nwant: %d, %v", tt.msg, data,
n, err, 0, ErrDecodeOverflow) n, err, 0, errDecodeOverflow)
} }
}() }()
} }
......
...@@ -320,6 +320,7 @@ package proto ...@@ -320,6 +320,7 @@ package proto
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"math" "math"
"reflect" "reflect"
"sort" "sort"
...@@ -917,7 +918,7 @@ func (d *decoderCommon) generatedCode() string { ...@@ -917,7 +918,7 @@ func (d *decoderCommon) generatedCode() string {
// NOTE for >0 check actual X in StdSizes{X} does not particularly matter // NOTE for >0 check actual X in StdSizes{X} does not particularly matter
if ((&types.StdSizes{8, 8}).Sizeof(d.typ) > 0 || d.enc != 'N') && d.overflow.gotoEmitted { if ((&types.StdSizes{8, 8}).Sizeof(d.typ) > 0 || d.enc != 'N') && d.overflow.gotoEmitted {
code.emit("\noverflow:") code.emit("\noverflow:")
code.emit("return 0, ErrDecodeOverflow") code.emit("return 0, &ErrDecodeOverflow{\"%s\"}", d.typeName)
} }
code.emit("}\n") code.emit("}\n")
...@@ -1155,7 +1156,8 @@ func (d *decoderM) genBasic(assignto string, typ *types.Basic, userType types.Ty ...@@ -1155,7 +1156,8 @@ func (d *decoderM) genBasic(assignto string, typ *types.Basic, userType types.Ty
// correct float, but data is too short - catch this to return // correct float, but data is too short - catch this to return
// 'ErrDecodeOverflow' instead of type error. // 'ErrDecodeOverflow' instead of type error.
d.emit(" err = mdecodeErr(%q, err)", d.pathName(assignto)) d.emit(" err = mdecodeErr(%q, err)", d.pathName(assignto))
d.emit(" if err == ErrDecodeOverflow {") d.emit(" errDecodeOverflow := new(ErrDecodeOverflow)")
d.emit(" if errors.As(err, &errDecodeOverflow) {")
d.emit(" return 0, err") d.emit(" return 0, err")
d.emit(" }") d.emit(" }")
d.emit(" tail, err = msgp.ReadNilBytes(data)") d.emit(" tail, err = msgp.ReadNilBytes(data)")
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment