diff --git a/mysql-test/main/disabled.def b/mysql-test/main/disabled.def index ff0f3ab1781c4..a38906361c562 100644 --- a/mysql-test/main/disabled.def +++ b/mysql-test/main/disabled.def @@ -16,4 +16,3 @@ mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 chang file_contents : MDEV-6526 these files are not installed anymore max_statement_time : cannot possibly work, depends on timing partition_open_files_limit : open_files_limit check broken by MDEV-18360 -gis-json : MDEV-39813 infinite recursion diff --git a/mysql-test/main/gis-json.result b/mysql-test/main/gis-json.result index 49ec773945866..9cb7cb774a2ec 100644 --- a/mysql-test/main/gis-json.result +++ b/mysql-test/main/gis-json.result @@ -123,19 +123,6 @@ Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function. # # End of 10.2 tests # -# -# MDEV-39813 ST_GeomFromGeoJSON does not control recursion depth -# -SELECT ST_GeomFromGeoJSON( -concat( -repeat('{"type":"GeometryCollection","geometries":[', 2000), -'{"type":"Point","coordinates":[0,0]}', -repeat(']}', 2000) -)) as exp; -exp -NULL -Warnings: -Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'st_geomfromgeojson' at position 473 # End of 10.6 tests # # MDEV-34079: ST_AsGeoJSON returns incorrect value for empty geometry diff --git a/mysql-test/main/gis-json.test b/mysql-test/main/gis-json.test index ca402d1c2ef43..022672ab9b669 100644 --- a/mysql-test/main/gis-json.test +++ b/mysql-test/main/gis-json.test @@ -59,16 +59,6 @@ SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')) --echo # End of 10.2 tests --echo # ---echo # ---echo # MDEV-39813 ST_GeomFromGeoJSON does not control recursion depth ---echo # - -SELECT ST_GeomFromGeoJSON( - concat( - repeat('{"type":"GeometryCollection","geometries":[', 2000), - '{"type":"Point","coordinates":[0,0]}', - repeat(']}', 2000) - )) as exp; --echo # End of 10.6 tests diff --git a/mysql-test/main/thread_stack_overrun.result b/mysql-test/main/thread_stack_overrun.result new file mode 100644 index 0000000000000..d55bcd2d67bdb --- /dev/null +++ b/mysql-test/main/thread_stack_overrun.result @@ -0,0 +1,11 @@ +# +# MDEV-39813 ST_GeomFromGeoJSON does not control recursion depth +# +SELECT ST_GeomFromGeoJSON( +concat( +repeat('{"type":"GeometryCollection","geometries":[', 2000), +'{"type":"Point","coordinates":[0,0]}', +repeat(']}', 2000) +)) as exp; +ERROR HY000: Thread stack overrun: # bytes used of a # byte stack, and # bytes needed. Consider increasing the thread_stack system variable. +# End of 12.3 tests diff --git a/mysql-test/main/thread_stack_overrun.test b/mysql-test/main/thread_stack_overrun.test new file mode 100644 index 0000000000000..43dcf18555d40 --- /dev/null +++ b/mysql-test/main/thread_stack_overrun.test @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-39813 ST_GeomFromGeoJSON does not control recursion depth +--echo # + +--replace_regex /[0-9]+ bytes used of a [0-9]+ byte stack, and [0-9]+ bytes needed/# bytes used of a # byte stack, and # bytes needed/ +--error ER_STACK_OVERRUN_NEED_MORE +SELECT ST_GeomFromGeoJSON( + concat( + repeat('{"type":"GeometryCollection","geometries":[', 2000), + '{"type":"Point","coordinates":[0,0]}', + repeat(']}', 2000) + )) as exp; + +--echo # End of 12.3 tests diff --git a/sql/spatial.cc b/sql/spatial.cc index 9c405283a0f1f..3aaa2201e2010 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -20,6 +20,7 @@ #include "spatial.h" #include "gstream.h" // Gis_read_stream #include "sql_string.h" // String +#include "sql_parse.h" // check_stack_overrun #include /* This is from item_func.h. Didn't want to #include the whole file. */ @@ -586,8 +587,10 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, uint key_len; int fcoll_type_found= 0, feature_type_found= 0; + if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) + return NULL; + const uint32_t *killed_ptr= (uint32_t *) je->killed_ptr; - int stack_p; if (json_read_value(je)) goto err_return; @@ -753,10 +756,8 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, create_geom: - stack_p= je->stack_p; json_scan_start(je, je->s.cs, coord_start, je->s.str_end); je->killed_ptr= killed_ptr; - je->stack_p= stack_p; if (res->reserve(1 + 4, 512)) goto err_return; @@ -770,10 +771,8 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, return result; handle_geometry_key: - stack_p= je->stack_p; json_scan_start(je, je->s.cs, geometry_start, je->s.str_end); je->killed_ptr= killed_ptr; - je->stack_p= stack_p; return create_from_json(buffer, je, er_on_3D, res); err_return: