vivkin / gason

Lightweight and fast JSON parser for C++
MIT License
338 stars 51 forks source link

gason doesn't handle JS Number.MIN_VALUE or MAX_VALUE #19

Open craigminihan opened 9 years ago

craigminihan commented 9 years ago

In JavaScript (NodeJS) Number.MIN_VALUE is 5e-324 and MAX_VALUE 1.7976931348623157e+308.

These numbers are parsed by gason as 0 and infinity respectively. C++ will handle these as literals quite happily so string2double must be causing an underflow and overflow.

I replicated this case with simple mods to test-suite.cpp on master:

void parse(const char *csource, bool ok) {
    char *source = strdup(csource);
    char *endptr;
    JsonValue value;
    JsonAllocator allocator;
    int result = jsonParse(source, &endptr, &value, allocator);
    printf("result is %d, value is: %g\n", result, value.fval);
    ++parsed;
    free(source);
}

int main() {
    pass(u8R"json(5e-324)json");
    pass(u8R"json(1.7976931348623157e+308)json");
    return 0;
}

The output is:

result is: 0, value is: 0
result is: 0, value is: inf

Working case example:

int main()
{
  double min = 5e-324;
  double max = 1.7976931348623157e+308;
  printf("Min: %g, Max: %g\n", min, max);
}

This program prints 'Min: 4.94066e-324, Max: 1.79769e+308'.

I see this problem on an Intel i7 under Debian 8. I guess on some other CPU architectures this test may not fail in this manner.

DBJDBJ commented 3 years ago

gason is forgiving when parsing the json input. No tests fail on bad numbers in a json string, because string2double() does not use strtod() , And that internal algorithm indeed has a problem with above-mentioned values.

In my fork, I can conditionally compile, for code to use strtod(). The above values are correctly parsed and three other tests of 45 do fail in that case. Those 3 tests do use deliberately wrong number input.

If whoever is willing to contribute with debugged string2double(), I could use that.