4

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?

Polynomial
  • 27,674
  • 12
  • 80
  • 107

1 Answers1

2

AFAIK there aren't any "invalid" values here; just values that aren't the one you were originally thinking of. So you, you don't have much to worry about in terms of denial of service. Note, by contrast, that decimal can have invalid binary representations - these will just throw an exception and the single call will fail - still not a denial-of-service (just: they'll see failure).

Personally, though, I'd advise that encoding a double as a long then to a string is probably doing things the hard / inefficient way. If you desperately need it as a string, consider base-64 encoding the bits instead.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900