From e8a930c617adc217780cf4a936d9e869d668d926 Mon Sep 17 00:00:00 2001 From: "mykyta.oleksiienko" Date: Thu, 19 Sep 2024 15:14:34 +0300 Subject: [PATCH] CASSGO-2 Marshal big int returns variable length slice. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The marshalBigInt return 8 bytes slice in all cases except for big.Int, which returns a variable length slice, but should be 8 bytes slice as well. patch by Mykyta Oleksiienko; reviewed by João Reis for CASSGO-2 --- CHANGELOG.md | 2 ++ marshal.go | 9 +++++++-- marshal_test.go | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20da746a0..ed7c42bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- CASSGO-2 + ## [1.7.0] - 2024-09-23 This release is the first after the donation of gocql to the Apache Software Foundation (ASF) diff --git a/marshal.go b/marshal.go index 4d0adb923..2708c54ea 100644 --- a/marshal.go +++ b/marshal.go @@ -77,7 +77,7 @@ type Unmarshaler interface { // tinyint, smallint, int | integer types | // tinyint, smallint, int | string | formatted as base 10 number // bigint, counter | integer types | -// bigint, counter | big.Int | +// bigint, counter | big.Int | according to cassandra bigint specification the big.Int value limited to int64 size(an eight-byte two's complement integer.) // bigint, counter | string | formatted as base 10 number // float | float32 | // double | float64 | @@ -671,7 +671,10 @@ func marshalBigInt(info TypeInfo, value interface{}) ([]byte, error) { case uint8: return encBigInt(int64(v)), nil case big.Int: - return encBigInt2C(&v), nil + if !v.IsInt64() { + return nil, marshalErrorf("marshal bigint: value %v out of range", &v) + } + return encBigInt(v.Int64()), nil case string: i, err := strconv.ParseInt(value.(string), 10, 64) if err != nil { @@ -773,6 +776,8 @@ func marshalVarint(info TypeInfo, value interface{}) ([]byte, error) { retBytes = make([]byte, 8) binary.BigEndian.PutUint64(retBytes, v) } + case big.Int: + retBytes = encBigInt2C(&v) default: retBytes, err = marshalBigInt(info, value) } diff --git a/marshal_test.go b/marshal_test.go index 6c139e6bc..73e08d870 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -247,6 +247,20 @@ var marshalTests = []struct { nil, nil, }, + { + NativeType{proto: 2, typ: TypeBigInt}, + []byte("\xf7\x0c\x6b\x14\x84\x49\x3b\x36\x4a\x36\x1e\x03\x34\x05"), + "-78635384813432117863538481343211", + MarshalError("can not marshal string to bigint: strconv.ParseInt: parsing \"-78635384813432117863538481343211\": value out of range"), + nil, + }, + { + NativeType{proto: 2, typ: TypeBigInt}, + []byte("\x20\x45\xce\x3b\x05\xef\x2d\xde\x51\xb9\x28\x76\x6d\x6e"), + "922337203685477692259749625974294", + MarshalError("can not marshal string to bigint: strconv.ParseInt: parsing \"922337203685477692259749625974294\": value out of range"), + nil, + }, { NativeType{proto: 2, typ: TypeBoolean}, []byte("\x00"),