Re: New Version Notification for draft-kamp-httpbis-structure-01.txt (fwd)

Hi Kazuho,

On Thu, Nov 17, 2016 at 10:06:04AM +0900, Kazuho Oku wrote:
> Hi,
> 
> Thank you for writing the draft.
> 
> Regarding the numbers, could we either exclude floating point from the
> specification or state that an integral number MUST be encoded without
> using a dot?
> 
> The reason I ask is because it is hard to correctly implement a parser
> for floating point numbers, and a bug in the parser would likely lead
> to a vulnerability [1]. Note that in some (if not most) of the
> programming languages you would need to implement your own number
> parser to meet the needs. For example, you cannot use sscanf in C,
> because depending on the locale the function allows use of decimal
> points other than '.'.
> 
> If we could exclude floating point numbers from the specification
> entirely or have a restriction something like above, parser
> implementors can refrain from implementing their own floating point
> number parsers until the specification in which they are interested in
> actually start using the notation.
> 
> Non-integral numbers are rarely used in the HTTP headers. The only one
> I can recall is the q value of Accept-Encoding, but it is not a
> floating-point but actually a fixed-point number (of three decimals
> below the point), which could have been represented by using integral
> numbers between 0 to 1000.
> 
>      weight = OWS ";" OWS "q=" qvalue
>      qvalue = ( "0" [ "." 0*3DIGIT ] )
>             / ( "1" [ "." 0*3("0") ] )

I'd like to avoid FP as well. However it's important to note that fixed
point numbers is not exempt from similar issues due to the way they are
encoded, since everyone will store them in floats/doubles, but the error
is limited to the mantissa precision. For example 64-bit double numbers
contain a 53 bit mantissa so we can easily see a difference in the lower
bits. Example :

  #include <stdio.h>
  #include <stdlib.h>

  int main(int argc, char **argv)
  {
        double f = atof(argv[1]);
        printf("input=%s float=%f\n", argv[1], f);
        return 0;
  }

  $ ./a.out $((1<<32)).000001
  input=4294967296.000001 float=4294967296.000001
  $ ./a.out $((1<<33)).000001
  input=8589934592.000001 float=8589934592.000002

In my opinion we don't care here. And maybe we can document the expected
minimal precision (eg: minimum 53 bits to be able to store a 32-bit
integral range with a 1/1000000 fractional precision.

Also it's pretty certain that developers will use atof() on fixed point
numbers, but at least the input can be sanitized easily by ensuring that
only digits, dot and - are allowed in it.

Regards,
Willy

Received on Thursday, 17 November 2016 05:54:17 UTC