1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-41630 ST_IsValid crashes on polygons with many rings

This commit is contained in:
Sergei Golubchik
2026-10-20 00:43:20 +02:00
parent b2bc6c2f70
commit 505cefc810
3 changed files with 36 additions and 9 deletions

View File

@@ -126,4 +126,16 @@ repeat('{"type":"GeometryCollection", "geometries":[', @len),
'{"type":"Point","coordinates":[0,0]}',
repeat(']}', @len)
)) as exp;
#
# MDEV-41630 ST_IsValid crashes on polygons with many rings
#
SET SESSION group_concat_max_len = 200000000;
SET @rings = (SELECT GROUP_CONCAT(
CONCAT('(', seq, ' 0,', seq+1, ' 0,', seq+1, ' 1,', seq, ' 1,', seq, ' 0)')
SEPARATOR ','
) FROM seq_1_to_100000);
SET @g = ST_GeomFromText(CONCAT('POLYGON(', @rings, ')'));
SELECT ST_IsValid(@g);
ST_IsValid(@g)
0
# End of 12.3 tests

View File

@@ -5,6 +5,7 @@
# making writing tests that depend on reaching
# the depth hard.
#
source include/have_sequence.inc;
source include/not_embedded.inc;
# MSAN with debug exceeds the stack early.
source include/not_msan_with_debug.inc;
@@ -12,7 +13,7 @@ if (`select count(*) from information_schema.system_variables
where variable_name='have_sanitizer'
and global_value REGEXP '(A|UB)SAN'`)
{
--skip Can't be run in UBSAN/ASAN (stack size predictability)
--skip Cannot be run in UBSAN/ASAN (stack size predictability)
}
#
@@ -189,4 +190,18 @@ SELECT ST_GeomFromGeoJSON(
)) as exp;
--enable_result_log
--echo #
--echo # MDEV-41630 ST_IsValid crashes on polygons with many rings
--echo #
SET SESSION group_concat_max_len = 200000000;
SET @rings = (SELECT GROUP_CONCAT(
CONCAT('(', seq, ' 0,', seq+1, ' 0,', seq+1, ' 1,', seq, ' 1,', seq, ' 0)')
SEPARATOR ','
) FROM seq_1_to_100000);
SET @g = ST_GeomFromText(CONCAT('POLYGON(', @rings, ')'));
SELECT ST_IsValid(@g);
--echo # End of 12.3 tests

View File

@@ -2273,10 +2273,10 @@ int Gis_polygon::is_valid(int *valid) const
collector.prepare_operation();
scan_it.init(&collector);
border_count= (char *) my_alloca(num_rings);
border_count= (char *) my_safe_alloca(num_rings);
bzero(border_count, num_rings);
touches_count= (char *) my_alloca(num_rings);
internals= (char *) my_alloca(num_rings);
touches_count= (char *) my_safe_alloca(num_rings);
internals= (char *) my_safe_alloca(num_rings);
while (scan_it.more_points())
{
@@ -2373,9 +2373,9 @@ int Gis_polygon::is_valid(int *valid) const
exit:
collector.reset();
scan_it.reset();
my_afree(border_count);
my_afree(touches_count);
my_afree(internals);
my_safe_afree(border_count, num_rings);
my_safe_afree(touches_count, num_rings);
my_safe_afree(internals, num_rings);
return result;
@@ -3993,7 +3993,7 @@ int Gis_multi_polygon::is_valid(int *valid) const
collector.prepare_operation();
scan_it.init(&collector);
internals= (char *) my_alloca(num_geometries);
internals= (char *) my_safe_alloca(num_geometries);
while (scan_it.more_points())
{
@@ -4064,7 +4064,7 @@ int Gis_multi_polygon::is_valid(int *valid) const
exit:
collector.reset();
scan_it.reset();
my_afree(internals);
my_safe_afree(internals, num_geometries);
return result;
}