From 8fb5dde858272ac4d9b34d3c771b6e4649f49858 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Thu, 14 May 2026 02:22:07 +0300 Subject: [PATCH] fix(protocol): serialize float32/float64/fkVector in big-endian The JavaScript client reads floats via readFloatBE/readDoubleBE, which expect IEEE-754 values in big-endian byte order. The Nim server was writing them with copyMem in native byte order, so on little-endian machines (x86_64) the JS side deserialized FLOAT64 values as garbage (e.g. 1.0 became 3.03865e-319). Fix serialization by casting to int32/int64 and using bigEndian32/ bigEndian64, mirroring the existing big-endian handling for ints. Apply the same fix to deserialization and to fkVector elements. --- src/barabadb/protocol/wire.nim | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/barabadb/protocol/wire.nim b/src/barabadb/protocol/wire.nim index 88963c7..259a132 100644 --- a/src/barabadb/protocol/wire.nim +++ b/src/barabadb/protocol/wire.nim @@ -169,12 +169,14 @@ proc serializeValue*(buf: var seq[byte], val: WireValue) = of fkFloat32: var fl = val.float32Val var bytes: array[4, byte] - copyMem(addr bytes, unsafeAddr fl, 4) + var i32 = cast[int32](fl) + bigEndian32(addr bytes, unsafeAddr i32) buf.add(bytes) of fkFloat64: var fl = val.float64Val var bytes: array[8, byte] - copyMem(addr bytes, unsafeAddr fl, 8) + var i64 = cast[int64](fl) + bigEndian64(addr bytes, unsafeAddr i64) buf.add(bytes) of fkString: buf.writeString(val.strVal) of fkBytes: buf.writeBytes(val.bytesVal) @@ -192,7 +194,8 @@ proc serializeValue*(buf: var seq[byte], val: WireValue) = for f in val.vecVal: var fl = f var bytes: array[4, byte] - copyMem(addr bytes, unsafeAddr fl, 4) + var i32 = cast[int32](fl) + bigEndian32(addr bytes, unsafeAddr i32) buf.add(bytes) of fkJson: buf.writeString(val.jsonVal) @@ -227,14 +230,18 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire var fl: float32 var bytes: array[4, byte] for i in 0..3: bytes[i] = buf[pos + i] - copyMem(addr fl, unsafeAddr bytes, 4) + var i32: int32 + bigEndian32(addr i32, unsafeAddr bytes) + fl = cast[float32](i32) pos += 4 result = WireValue(kind: fkFloat32, float32Val: fl) of fkFloat64: var fl: float64 var bytes: array[8, byte] for i in 0..7: bytes[i] = buf[pos + i] - copyMem(addr fl, unsafeAddr bytes, 8) + var i64: int64 + bigEndian64(addr i64, unsafeAddr bytes) + fl = cast[float64](i64) pos += 8 result = WireValue(kind: fkFloat64, float64Val: fl) of fkString: @@ -270,7 +277,9 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire var fl: float32 var bytes: array[4, byte] for j in 0..3: bytes[j] = buf[pos + j] - copyMem(addr fl, unsafeAddr bytes, 4) + var i32: int32 + bigEndian32(addr i32, unsafeAddr bytes) + fl = cast[float32](i32) pos += 4 vec.add(fl) result = WireValue(kind: fkVector, vecVal: vec)