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.
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user