|
libbson does not consistently error when parsing integers that exceed the range of unsigned integer 64 limits, sometimes parsing them as a 32 bit integer.
Here is a simple repro:
#include <mongoc/mongoc.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
|
int
|
main (int argc, char *argv[])
|
{
|
bson_t bson;
|
bson_error_t error;
|
char* data = bson_strdup_printf("{ \"val\" : %s }", argv[1]);
|
bool ret;
|
|
mongoc_init ();
|
ret = bson_init_from_json (&bson, data, strlen(data), &error);
|
if (!ret) {
|
printf ("error: %s", error.message);
|
}
|
printf ("%s", bson_as_canonical_extended_json (&bson, NULL));
|
mongoc_cleanup ();
|
|
return EXIT_SUCCESS;
|
}
|
For an input integer that is just greater than int64 limits (2 ^ 63), this returns an error:
./repro "9223372036854775808"
|
error: Number "9223372036854775808" is out of range{ }
|
But for an input integer that is greater than uint64 limits (2 ^ 64 + 1), this is sometimes parsed as a 32 bit integer with no error:
./repro "18446744073709551617"
|
{ "val" : { "$numberInt" : "1" } }
|
The extended JSON spec suggests that integers beyond the representable range should be parsed as a double with loss of precision.
If a parser is unable to represent the number exactly as an integer (e.g. a large 64-bit number on a 32-bit platform), it MUST interpret it as a BSON Double even if this results in a loss of precision.
|