From 099caf826fd1803e5199c0cd1863517fa3390bae Mon Sep 17 00:00:00 2001 From: Knut Anders Hatlen Date: Wed, 8 Jul 2015 14:51:09 +0200 Subject: [PATCH] Bug#21384048: ASSERTION FAILED: N >= 0 && N <= 308 IN RAPIDJSON::INTERNAL::FASTPATH An assertion was hit in rapidjson when parsing a JSON text that contained a floating point number with a large, negative exponent. The bug is fixed upstream in this bug report: https://github.com/miloyip/rapidjson/issues/313 This patch applies the upstream fix to extra/rapidjson/include/rapidjson/reader.h. --- extra/RAPIDJSON-README | 16 ++++++++--- extra/rapidjson/include/rapidjson/reader.h | 20 ++++++++++--- mysql-test/r/json.result | 28 +++++++++++++++++++ .../suite/gis/r/geojson_functions.result | 12 ++++++++ mysql-test/suite/gis/t/geojson_functions.test | 13 +++++++++ mysql-test/t/json.test | 18 ++++++++++++ 6 files changed, 99 insertions(+), 8 deletions(-) diff --git a/extra/RAPIDJSON-README b/extra/RAPIDJSON-README index b69d8e7088c1..8ef0b6258641 100644 --- a/extra/RAPIDJSON-README +++ b/extra/RAPIDJSON-README @@ -19,11 +19,19 @@ The rapidjson library included in this directory is based on https://github.com/miloyip/rapidjson, upstream commit 3a4835e080d213c60842f58f207991fbb1c97f74. -There are two changes made to the library: +There are three changes made to the library: -1) Two lines has been added to reader.h, which fixes an assertion in the library - when a JSON document contains illegaly escaped unicode characters. See +1) Two lines have been added to reader.h, which fix an assertion in the library + when a JSON document contains illegally escaped unicode characters. See upstream commit b7e34100ed167b8134b41fcff0918895dd4e61fb for the changes. 2) Rapidjson-specific changes in commit 91153f3385c4917a215aa4c7818b3f6265608286 - has been applied, so that negative zero is handled properly. + have been applied, so that negative zero is handled properly (bug#19504183). + +3) The fix for a bug in the parsing of floating point numbers has been + applied to reader.h (bug#21384048). See details in the upstream bug + report at https://github.com/miloyip/rapidjson/issues/313 and the + following upstream commits: + - 93d13ad2acc6a52d58e09d84e76826cd36ee64f0 + - 735354efd328709a8efb6a2a43a584bb85f2de6b + - 7708215b609733bcfa06074b67463920c03782e8 diff --git a/extra/rapidjson/include/rapidjson/reader.h b/extra/rapidjson/include/rapidjson/reader.h index 6e8faac8aef5..64a9977898b3 100644 --- a/extra/rapidjson/include/rapidjson/reader.h +++ b/extra/rapidjson/include/rapidjson/reader.h @@ -931,10 +931,22 @@ class GenericReader { if (s.Peek() >= '0' && s.Peek() <= '9') { exp = s.Take() - '0'; - while (s.Peek() >= '0' && s.Peek() <= '9') { - exp = exp * 10 + (s.Take() - '0'); - if (exp > 308 && !expMinus) // exp > 308 should be rare, so it should be checked first. - RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + if (expMinus) { + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp >= 214748364) { // Issue #313: prevent overflow exponent + while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp > maxExp) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + } } } else diff --git a/mysql-test/r/json.result b/mysql-test/r/json.result index 3a7d549f7f34..1b4b382b20f5 100644 --- a/mysql-test/r/json.result +++ b/mysql-test/r/json.result @@ -12786,3 +12786,31 @@ NULL 4 1 NULL 5 1 NULL NULL 5 DROP TABLE t; +# +# Bug#21384048 ASSERTION FAILED: N >= 0 && N <= 308 +# IN RAPIDJSON::INTERNAL::FASTPATH +# +SELECT JSON_EXTRACT('-1E-36181012216111515851075235238', '$'); +JSON_EXTRACT('-1E-36181012216111515851075235238', '$') +-0 +SELECT JSON_EXTRACT('1E-36181012216111515851075235238', '$'); +JSON_EXTRACT('1E-36181012216111515851075235238', '$') +0 +SELECT JSON_EXTRACT('1E-325', '$'); +JSON_EXTRACT('1E-325', '$') +0 +SELECT JSON_EXTRACT('1E-324', '$'); +JSON_EXTRACT('1E-324', '$') +0 +SELECT JSON_EXTRACT('1E-323', '$'); +JSON_EXTRACT('1E-323', '$') +1e-323 +SELECT JSON_EXTRACT('1E+308', '$'); +JSON_EXTRACT('1E+308', '$') +1e308 +SELECT JSON_EXTRACT('1E+309', '$'); +ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "Number too big to be stored in double." at position 6 in '1E+309'. +SELECT JSON_EXTRACT('1E+36181012216111515851075235238', '$'); +ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "Number too big to be stored in double." at position 6 in '1E+36181012216111515851075235238'. +SELECT JSON_EXTRACT('-1E+36181012216111515851075235238', '$'); +ERROR 22032: Invalid JSON text in argument 1 to function json_extract: "Number too big to be stored in double." at position 7 in '-1E+36181012216111515851075235238'. diff --git a/mysql-test/suite/gis/r/geojson_functions.result b/mysql-test/suite/gis/r/geojson_functions.result index 6fcb738e5b6d..27be7e990257 100644 --- a/mysql-test/suite/gis/r/geojson_functions.result +++ b/mysql-test/suite/gis/r/geojson_functions.result @@ -4114,3 +4114,15 @@ ST_SRID(ST_GeomFromGeoJSON(geojson_value)) 1 200004 DROP TABLE geojson; +# +# Bug#21384048 ASSERTION FAILED: N >= 0 && N <= 308 +# IN RAPIDJSON::INTERNAL::FASTPATH +# +SELECT ST_GEOMFROMGEOJSON('1E-36181012216111515851075235238'); +ERROR HY000: Invalid GeoJSON data provided to function st_geomfromgeojson +SELECT ST_GEOMFROMGEOJSON('-1E-36181012216111515851075235238'); +ERROR HY000: Invalid GeoJSON data provided to function st_geomfromgeojson +SELECT ST_GEOMFROMGEOJSON('1E+36181012216111515851075235238'); +ERROR 22032: Invalid JSON text in argument 1 to function st_geomfromgeojson: "Number too big to be stored in double." at position 6 in '1E+36181012216111515851075235238'. +SELECT ST_GEOMFROMGEOJSON('-1E+36181012216111515851075235238'); +ERROR 22032: Invalid JSON text in argument 1 to function st_geomfromgeojson: "Number too big to be stored in double." at position 7 in '-1E+36181012216111515851075235238'. diff --git a/mysql-test/suite/gis/t/geojson_functions.test b/mysql-test/suite/gis/t/geojson_functions.test index 9108a38447c1..4048ec0a6871 100644 --- a/mysql-test/suite/gis/t/geojson_functions.test +++ b/mysql-test/suite/gis/t/geojson_functions.test @@ -3799,3 +3799,16 @@ SELECT ST_AsText(ST_GeomFromGeoJSON(geojson_value)) FROM geojson; SELECT ST_SRID(ST_GeomFromGeoJSON(geojson_value)) FROM geojson; DROP TABLE geojson; + +--echo # +--echo # Bug#21384048 ASSERTION FAILED: N >= 0 && N <= 308 +--echo # IN RAPIDJSON::INTERNAL::FASTPATH +--echo # +--error ER_INVALID_GEOJSON_UNSPECIFIED +SELECT ST_GEOMFROMGEOJSON('1E-36181012216111515851075235238'); +--error ER_INVALID_GEOJSON_UNSPECIFIED +SELECT ST_GEOMFROMGEOJSON('-1E-36181012216111515851075235238'); +--error ER_INVALID_JSON_TEXT_IN_PARAM +SELECT ST_GEOMFROMGEOJSON('1E+36181012216111515851075235238'); +--error ER_INVALID_JSON_TEXT_IN_PARAM +SELECT ST_GEOMFROMGEOJSON('-1E+36181012216111515851075235238'); diff --git a/mysql-test/t/json.test b/mysql-test/t/json.test index 53cb500560bc..c7d03852f78a 100644 --- a/mysql-test/t/json.test +++ b/mysql-test/t/json.test @@ -5737,6 +5737,24 @@ SELECT JSON_EXTRACT('{"a":1}', '$.a') AS je, a, COUNT(DISTINCT a) FROM t GROUP BY a, je WITH ROLLUP; DROP TABLE t; +--echo # +--echo # Bug#21384048 ASSERTION FAILED: N >= 0 && N <= 308 +--echo # IN RAPIDJSON::INTERNAL::FASTPATH +--echo # +SELECT JSON_EXTRACT('-1E-36181012216111515851075235238', '$'); +SELECT JSON_EXTRACT('1E-36181012216111515851075235238', '$'); +SELECT JSON_EXTRACT('1E-325', '$'); +SELECT JSON_EXTRACT('1E-324', '$'); +SELECT JSON_EXTRACT('1E-323', '$'); +SELECT JSON_EXTRACT('1E+308', '$'); +--error ER_INVALID_JSON_TEXT_IN_PARAM +SELECT JSON_EXTRACT('1E+309', '$'); +--error ER_INVALID_JSON_TEXT_IN_PARAM +SELECT JSON_EXTRACT('1E+36181012216111515851075235238', '$'); +--error ER_INVALID_JSON_TEXT_IN_PARAM +SELECT JSON_EXTRACT('-1E+36181012216111515851075235238', '$'); + + # Local Variables: # mode: sql # sql-product: mysql