Be more careful about checking for overflow when parsing numbers

This commit is contained in:
Eric Fischer 2017-11-09 12:11:07 -08:00
parent 5a68886b4d
commit 87ce5b9310
5 changed files with 49 additions and 6 deletions

View File

@ -1,3 +1,7 @@
## 1.26.6
* Be more careful about checking for overflow when parsing numbers
## 1.26.5
* Support UTF-16 surrogate pairs in JSON strings

24
mvt.cpp
View File

@ -517,14 +517,28 @@ mvt_value stringified_to_mvt_value(int type, const char *s) {
tv.numeric_value.sint_value = v;
}
} else {
double d = atof(s);
errno = 0;
char *endptr;
if (d == (float) d) {
tv.type = mvt_float;
tv.numeric_value.float_value = d;
} else {
float f = strtof(s, &endptr);
if (endptr == s || ((f == HUGE_VAL || f == HUGE_VALF || f == HUGE_VALL) && errno == ERANGE)) {
double d = strtod(s, &endptr);
if (endptr == s || ((d == HUGE_VAL || d == HUGE_VALF || d == HUGE_VALL) && errno == ERANGE)) {
fprintf(stderr, "Warning: numeric value %s could not be represented\n", s);
}
tv.type = mvt_double;
tv.numeric_value.double_value = d;
} else {
double d = atof(s);
if (f == d) {
tv.type = mvt_float;
tv.numeric_value.float_value = f;
} else {
// Conversion succeeded, but lost precision, so use double
tv.type = mvt_double;
tv.numeric_value.double_value = d;
}
}
}
} else if (type == mvt_bool) {

3
tests/overflow/in.json Normal file
View File

@ -0,0 +1,3 @@
{ "type": "Feature", "properties": { "excess": 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 }, "geometry": { "type": "Point", "coordinates": [ 0,0 ] } }
{ "type": "Feature", "properties": { "excess": 22e291 }, "geometry": { "type": "Point", "coordinates": [ 0,0 ] } }
{ "type": "Feature", "properties": { "excess": 2.5 }, "geometry": { "type": "Point", "coordinates": [ 0,0 ] } }

View File

@ -0,0 +1,22 @@
{ "type": "FeatureCollection", "properties": {
"bounds": "0.000000,0.000000,0.000000,0.000000",
"center": "0.000000,0.000000,0",
"description": "tests/overflow/out/-z0.json.check.mbtiles",
"format": "pbf",
"json": "{\"vector_layers\": [ { \"id\": \"in\", \"description\": \"\", \"minzoom\": 0, \"maxzoom\": 0, \"fields\": {\"excess\": \"Number\"} } ],\"tilestats\": {\"layerCount\": 1,\"layers\": [{\"layer\": \"in\",\"count\": 3,\"geometry\": \"Point\",\"attributeCount\": 1,\"attributes\": [{\"attribute\": \"excess\",\"count\": 3,\"type\": \"number\",\"values\": [2.2222222222222223e+291,2.2e+292,2.5],\"min\": 2.5,\"max\": 2.2e+292}]}]}}",
"maxzoom": "0",
"minzoom": "0",
"name": "tests/overflow/out/-z0.json.check.mbtiles",
"type": "overlay",
"version": "2"
}, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "excess": 2.2222222222222223e+291 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": 2.2e+292 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": 2.5 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
] }
] }
] }

View File

@ -1,6 +1,6 @@
#ifndef VERSION_HPP
#define VERSION_HPP
#define VERSION "tippecanoe v1.26.5\n"
#define VERSION "tippecanoe v1.26.6\n"
#endif