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:
|
of fkFloat32:
|
||||||
var fl = val.float32Val
|
var fl = val.float32Val
|
||||||
var bytes: array[4, byte]
|
var bytes: array[4, byte]
|
||||||
copyMem(addr bytes, unsafeAddr fl, 4)
|
var i32 = cast[int32](fl)
|
||||||
|
bigEndian32(addr bytes, unsafeAddr i32)
|
||||||
buf.add(bytes)
|
buf.add(bytes)
|
||||||
of fkFloat64:
|
of fkFloat64:
|
||||||
var fl = val.float64Val
|
var fl = val.float64Val
|
||||||
var bytes: array[8, byte]
|
var bytes: array[8, byte]
|
||||||
copyMem(addr bytes, unsafeAddr fl, 8)
|
var i64 = cast[int64](fl)
|
||||||
|
bigEndian64(addr bytes, unsafeAddr i64)
|
||||||
buf.add(bytes)
|
buf.add(bytes)
|
||||||
of fkString: buf.writeString(val.strVal)
|
of fkString: buf.writeString(val.strVal)
|
||||||
of fkBytes: buf.writeBytes(val.bytesVal)
|
of fkBytes: buf.writeBytes(val.bytesVal)
|
||||||
@@ -192,7 +194,8 @@ proc serializeValue*(buf: var seq[byte], val: WireValue) =
|
|||||||
for f in val.vecVal:
|
for f in val.vecVal:
|
||||||
var fl = f
|
var fl = f
|
||||||
var bytes: array[4, byte]
|
var bytes: array[4, byte]
|
||||||
copyMem(addr bytes, unsafeAddr fl, 4)
|
var i32 = cast[int32](fl)
|
||||||
|
bigEndian32(addr bytes, unsafeAddr i32)
|
||||||
buf.add(bytes)
|
buf.add(bytes)
|
||||||
of fkJson:
|
of fkJson:
|
||||||
buf.writeString(val.jsonVal)
|
buf.writeString(val.jsonVal)
|
||||||
@@ -227,14 +230,18 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire
|
|||||||
var fl: float32
|
var fl: float32
|
||||||
var bytes: array[4, byte]
|
var bytes: array[4, byte]
|
||||||
for i in 0..3: bytes[i] = buf[pos + i]
|
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
|
pos += 4
|
||||||
result = WireValue(kind: fkFloat32, float32Val: fl)
|
result = WireValue(kind: fkFloat32, float32Val: fl)
|
||||||
of fkFloat64:
|
of fkFloat64:
|
||||||
var fl: float64
|
var fl: float64
|
||||||
var bytes: array[8, byte]
|
var bytes: array[8, byte]
|
||||||
for i in 0..7: bytes[i] = buf[pos + i]
|
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
|
pos += 8
|
||||||
result = WireValue(kind: fkFloat64, float64Val: fl)
|
result = WireValue(kind: fkFloat64, float64Val: fl)
|
||||||
of fkString:
|
of fkString:
|
||||||
@@ -270,7 +277,9 @@ proc deserializeValue*(buf: openArray[byte], pos: var int, depth: int = 0): Wire
|
|||||||
var fl: float32
|
var fl: float32
|
||||||
var bytes: array[4, byte]
|
var bytes: array[4, byte]
|
||||||
for j in 0..3: bytes[j] = buf[pos + j]
|
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
|
pos += 4
|
||||||
vec.add(fl)
|
vec.add(fl)
|
||||||
result = WireValue(kind: fkVector, vecVal: vec)
|
result = WireValue(kind: fkVector, vecVal: vec)
|
||||||
|
|||||||
Reference in New Issue
Block a user