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:
committed by
Daniel Black
parent
f9d797f1cc
commit
89c4d2f00c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user