Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generalListDecoder panics when iterator timeout on decoding message #19

Open
xnslong opened this issue May 14, 2020 · 0 comments
Open

Comments

@xnslong
Copy link

xnslong commented May 14, 2020

When decoding a message, the Decoder.Decode method is called. (the following code snippet)

Line 24 (L24) tries to decode the message, and it will check the error of iter on decoding finished (L25). However, the L24 may panic (instead of return normally). When the L24 panics, the whole method will panic, not returning the expected error.

go/decoder.go

Lines 16 to 29 in 9b5a675

func (decoder *Decoder) Decode(val interface{}) error {
cfg := decoder.cfg
valType := reflect.TypeOf(val)
valDecoder := cfg.getGenDecoder(valType)
if valDecoder == nil {
valDecoder = cfg.decoderOf(valType)
cfg.addGenDecoder(valType, valDecoder)
}
valDecoder.Decode(val, decoder.iter)
if decoder.iter.Error() != nil {
return decoder.iter.Error()
}
return nil
}

Following is the method where panic may occur.

The underlying Reader of iter may read from a TCP connection (L13). But TCP connection can run timeout, then the underlying Reader will get an error. When such error occurs, the iter will return zero values and set an error. (thus elemType == TypeStop && length == 0 && iter.Error() != nil) When trying to get the generalReaderOf(TypeStop) (L14), this method will panic (See the code snippet, go/general/decode.go#L31).

func (decoder *generalListDecoder) Decode(val interface{}, iter spi.Iterator) {
*val.(*List) = readList(iter).(List)
}
func readList(iter spi.Iterator) interface{} {
elemType, length := iter.ReadListHeader()
generalReader := generalReaderOf(elemType)
var generalList List
for i := 0; i < length; i++ {
generalList = append(generalList, generalReader(iter))
}
return generalList
}

go/general/decode.go

Lines 8 to 33 in 9b5a675

func generalReaderOf(ttype protocol.TType) func(iter spi.Iterator) interface{} {
switch ttype {
case protocol.TypeBool:
return readBool
case protocol.TypeI08:
return readInt8
case protocol.TypeI16:
return readInt16
case protocol.TypeI32:
return readInt32
case protocol.TypeI64:
return readInt64
case protocol.TypeString:
return readString
case protocol.TypeDouble:
return readFloat64
case protocol.TypeList:
return readList
case protocol.TypeMap:
return readMap
case protocol.TypeStruct:
return readStruct
default:
panic("unsupported type")
}
}

@xnslong xnslong changed the title generalListDecoder panics when iterator prematurely ends on decoding message generalListDecoder panics when iterator timeout on decoding message May 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant