I'm writing a custom deserialisation system for packetising data over the network, and am serialising doubles in the following way:
private static string EncodeDouble(double raw)
{
long value = BitConverter.DoubleToInt64Bits(raw);
return EncodeInteger(value);
}
The EncodeInteger
function simply turns the integer into a tagged string, so that the deserialisation code knows that it's got the right data type.
On the other side, I'm deserialising as follows:
private static double DecodeDouble(string raw)
{
long value = DecodeInteger<long>(raw);
return BitConverter.Int64BitsToDouble(value);
}
Again, DecodeInteger
just removes the tag and verifies that the value is within range for a long, then casts to a long. That's safe, because if anything goes wrong it'll just throw an exception.
The reason for my concern is that, after stepping into the reference source, I see this direct unsafe cast:
public static unsafe double Int64BitsToDouble(long value) {
return *((double *)&value);
}
The problem I forsee is that the value of the long can be arbitrarily modified, because it's going over the network. I'm not bothered about the value being modified arbitrarily, but rather the potential for the CLR running into issues with if an invalid underlying double
representation is sent.
I'm unsure if there are any potential long
values that don't map to a valid double
, but if there are, what am I likely to see? Would the CLR crash, leading to a denial of service condition? Or is there an exception that can be caught?