acbcce09467e251633c09a96a239029c2b159221 | Author: Pekka Enberg <penberg@scylladb.com>
| 2016-07-27 10:10:37+03:00
marshal: Fix unmarshalUDT for less values than UDT fields
The CQL binary protocol specification states that a serialized UDT is
allowed to have _less_ values than it has fields:
"A UDT value will generally have one value for each field of the type
it represents, but it is allowed to have less values than the type has
fields."
This is also evident in the Cassandra Java driver's UDTCodec class:
public UDTValue deserialize(ByteBuffer bytes) {
ByteBuffer input = bytes.duplicate();
UDTValue value = definition.newValue();
int i = 0;
while (input.hasRemaining() && i < value.values.length) {
int n = input.getInt();
value.values[i++] = n < 0 ? null : readBytes(input, n);
}
return value;
}
Fix the unmarshalUDT() function to check whether there's more data to
read to avoid accessing a slice out of bounds:
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
github.com/gocql/gocql.unmarshalUDT(0x7ffff7fbc380, 0xc208030c60, 0x0, 0x0, 0x0, 0x694f60, 0xc208094da0, 0x0, 0x0)
/disk/GOPATH/src/github.com/gocql/gocql/marshal.go:1654 +0x574
github.com/gocql/gocql.Unmarshal(0x7ffff7fbc380, 0xc208030c60, 0x0, 0x0, 0x0, 0x694f60, 0xc208094da0, 0x0, 0x0)
/disk/GOPATH/src/github.com/gocql/gocql/marshal.go:157 +0x9b7
github.com/gocql/gocql.(*Iter).Scan(0xc20806c630, 0xc20800adc0, 0x1, 0x1, 0x7ffff7fa9000)
/disk/GOPATH/src/github.com/gocql/gocql/session.go:1084 +0x6ff
github.com/gocql/gocql.(*Query).Scan(0xc208082700, 0xc20800adc0, 0x1, 0x1, 0x0, 0x0)
/disk/GOPATH/src/github.com/gocql/gocql/session.go:918 +0xab
main.main()
/home/a.go:86 +0x4cd
Fixes #757.