MDEV-36168 ASAN error in Item_func_latlongfromgeohash::decode_geohash

decode_geohash now properly filters non ASCII values from the input.
This commit is contained in:
Dave Gosselin 2025-03-26 16:53:30 -04:00 committed by Dave Gosselin
parent 8055a00ab5
commit 29c9dbb883
4 changed files with 30 additions and 6 deletions

View File

@ -1654,3 +1654,10 @@ SELECT ST_AsText(ST_PointFromGeohash(col1, 4326)) FROM t1;
ST_AsText(ST_PointFromGeohash(col1, 4326)) ST_AsText(ST_PointFromGeohash(col1, 4326))
POINT(-145 49.3) POINT(-145 49.3)
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-36168 ASAN global-buffer-overflow in Item_func_latlongfromgeohash::decode_geohash
#
SELECT ST_LatFromGeoHash("ї");
ERROR HY000: Incorrect geohash value: '\0457' for function st_latfromgeohash
SELECT ST_LongFromGeoHash("ї");
ERROR HY000: Incorrect geohash value: '\0457' for function st_longfromgeohash

View File

@ -1453,3 +1453,11 @@ SELECT ST_LatFromGeohash(col1) FROM t1;
SELECT ST_LongFromGeohash(col1) FROM t1; SELECT ST_LongFromGeohash(col1) FROM t1;
SELECT ST_AsText(ST_PointFromGeohash(col1, 4326)) FROM t1; SELECT ST_AsText(ST_PointFromGeohash(col1, 4326)) FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-36168 ASAN global-buffer-overflow in Item_func_latlongfromgeohash::decode_geohash
--echo #
--error ER_WRONG_VALUE_FOR_TYPE
SELECT ST_LatFromGeoHash("ї");
--error ER_WRONG_VALUE_FOR_TYPE
SELECT ST_LongFromGeoHash("ї");

View File

@ -3027,6 +3027,15 @@ const uint8_t Item_func_latlongfromgeohash::geohash_alphabet[256] = {
}; };
bool Item_func_latlongfromgeohash::convert_character(char in, int &out)
{
if (in < 0)
return true;
out= Item_func_latlongfromgeohash::geohash_alphabet[(int) in];
return false;
}
/** /**
Decodes a geohash string into longitude and latitude. Decodes a geohash string into longitude and latitude.
The results are rounded, based on the length of input geohash. The function The results are rounded, based on the length of input geohash. The function
@ -3053,10 +3062,9 @@ bool Item_func_latlongfromgeohash::decode_geohash(
for (uint i = 0; i < input_length; i++) for (uint i = 0; i < input_length; i++)
{ {
int converted_character = int converted_character= -1;
Item_func_latlongfromgeohash::geohash_alphabet[(int) (*geohash)[i]]; if (convert_character((*geohash)[i], converted_character) ||
converted_character == 255) {
if (converted_character == 255) {
return true; return true;
} }

View File

@ -1317,12 +1317,13 @@ public:
class Item_func_latlongfromgeohash : public Item_real_func class Item_func_latlongfromgeohash : public Item_real_func
{ {
private: private:
String buf; String buf;
static const uint8_t geohash_alphabet[256]; static const uint8_t geohash_alphabet[256];
const bool decode_longitude; const bool decode_longitude;
static bool convert_character(char in, int &out);
public: public:
Item_func_latlongfromgeohash(THD *thd, Item *a, bool start_on_even_bit_arg) Item_func_latlongfromgeohash(THD *thd, Item *a, bool start_on_even_bit_arg)
: Item_real_func(thd, a), : Item_real_func(thd, a),
decode_longitude(start_on_even_bit_arg) {} decode_longitude(start_on_even_bit_arg) {}