Fix panic in protocol.Decode Decode function was checking if the message was too short to be valid by comparing the length of the message with 4*((numTags-1)+numTag), which is not the correct minimum size of the valid message (the correct minimum size is 4*(1+(numTags-1)+numTag)). That's why the message with the size of 4*((numTags-1)+numTag) was causing slice index out of bounds in the subsequent payload access (the shortest message that would trigger this is [1, 0, 0, 0]). Change-Id: I52a518bd5d89f07038ac3525094a0db0f76b2c29
diff --git a/go/protocol/protocol.go b/go/protocol/protocol.go index ad8f7dd..9d409ef 100644 --- a/go/protocol/protocol.go +++ b/go/protocol/protocol.go
@@ -89,7 +89,7 @@ var payloadSum uint64 for _, payload := range msg { - if len(payload) % 4 != 0 { + if len(payload)%4 != 0 { return nil, errors.New("encode: length of value is not a multiple of four") } payloadSum += uint64(len(payload)) @@ -139,7 +139,7 @@ if len(bytes) < 4 { return nil, errors.New("decode: message too short to be valid") } - if len(bytes) % 4 != 0 { + if len(bytes)%4 != 0 { return nil, errors.New("decode: message is not a multiple of four bytes") } @@ -149,13 +149,15 @@ return make(map[uint32][]byte), nil } - if uint64(len(bytes)) < 4*((numTags-1)+numTags) { + minLen := 4 * (1 + (numTags - 1) + numTags) + + if uint64(len(bytes)) < minLen { return nil, errors.New("decode: message too short to be valid") } offsets := bytes[4:] tags := bytes[4*(1+numTags-1):] - payloads := bytes[4*(1+(numTags-1)+numTags):] + payloads := bytes[minLen:] if len(payloads) > math.MaxInt32 { return nil, errors.New("decode: message too large")