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

MDEV-38669: ASAN fail in Item_func_collect::add during ST_COLLECT

st_collect read past the end of its input because it assumed
that the input was a valid geometry.  Check that the length of the
input is at least long enough to possibly contain a valid geometry.
This commit is contained in:
Dave Gosselin
2026-06-15 15:03:50 -04:00
committed by Daniel Black
parent f9d797f1cc
commit 89c4d2f00c
5 changed files with 45 additions and 1 deletions

View File

@@ -279,4 +279,22 @@ SELECT ST_ASTEXT(ST_ENVELOPE(ST_COLLECT(c))) FROM t;
ST_ASTEXT(ST_ENVELOPE(ST_COLLECT(c)))
NULL
DROP TABLE t;
#
# MDEV-38669 ST_COLLECT reads past the end of a non-geometry argument
#
SELECT ST_COLLECT('');
ST_COLLECT('')
NULL
SELECT ST_COLLECT('') IS NULL;
ST_COLLECT('') IS NULL
1
SELECT ST_COLLECT('not wkb');
ST_COLLECT('not wkb')
NULL
CREATE TABLE t1 (a VARCHAR(16));
INSERT INTO t1 VALUES (''), ('not wkb'), (NULL);
SELECT ST_COLLECT(a) FROM t1;
ST_COLLECT(a)
NULL
DROP TABLE t1;
# End of 12.3 tests

View File

@@ -240,4 +240,15 @@ SELECT ST_ASTEXT(ST_ENVELOPE(ST_COLLECT(c))) FROM t;
DROP TABLE t;
--echo #
--echo # MDEV-38669 ST_COLLECT reads past the end of a non-geometry argument
--echo #
SELECT ST_COLLECT('');
SELECT ST_COLLECT('') IS NULL;
SELECT ST_COLLECT('not wkb');
CREATE TABLE t1 (a VARCHAR(16));
INSERT INTO t1 VALUES (''), ('not wkb'), (NULL);
SELECT ST_COLLECT(a) FROM t1;
DROP TABLE t1;
--echo # End of 12.3 tests

View File

@@ -4642,6 +4642,13 @@ bool Item_func_collect::add() {
if (tmp_arg[0]->null_value)
return 0;
/*
A value too short to hold the SRID and WKB header isn't a valid
geometry, so contribute nothing (NULL) to the aggregate.
*/
if (!Geometry::is_valid_geometry_length(wkb->length()))
return 0;
if(is_distinct && list_contains_element(wkb))
return 0;

View File

@@ -351,7 +351,7 @@ Geometry *Geometry::construct(Geometry_buffer *buffer,
uint32 geom_type;
Geometry *result;
if (data_len < SRID_SIZE + WKB_HEADER_SIZE) // < 4 + (1 + 4)
if (!is_valid_geometry_length(data_len))
return NULL;
/* + 1 to skip the byte order (stored in position SRID_SIZE). */
geom_type= uint4korr(data + SRID_SIZE + 1);

View File

@@ -325,6 +325,14 @@ public:
static Geometry *construct(Geometry_buffer *buffer,
const char *data, uint32 data_len);
/*
A WKB starts with a SRID and a WKB header. A buffer shorter than
the length of these together cannot possibly hold a geometry.
*/
static bool is_valid_geometry_length(uint32 data_len)
{
return data_len >= SRID_SIZE + WKB_HEADER_SIZE;
}
static Geometry *create_from_wkt(Geometry_buffer *buffer,
Gis_read_stream *trs, String *wkt,
bool init_stream=1);