Skip to content

Commit d050128

Browse files
committed
MDEV-39481 ASAN error on malformed WKB polygon
let's make is difficult for wkb and len to desync
1 parent bedacb3 commit d050128

3 files changed

Lines changed: 41 additions & 26 deletions

File tree

mysql-test/main/gis.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5583,4 +5583,16 @@ set sql_mode= @orig_sql_mode;
55835583
select st_astext(st_geomfromwkb(x'0103000000020000000400000000000000000000000000000000000000000000000000f03f0000000000000000000000000000f03f000000000000f03f0000000000000000000000000000000005000000000000000000e03f000000000000e03f')) 'no asan error here';
55845584
no asan error here
55855585
NULL
5586+
SELECT ST_GeomFromWKB(x'0103000000020000000400000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000000001000000') IS NOT NULL AS pg;
5587+
pg
5588+
0
5589+
SELECT ST_GeomFromWKB(x'01050000000200000001020000000200000000000000000000000000000000000000000000000000F03F000000000000F03F01020000000100000000000000000000') IS NOT NULL AS ml;
5590+
ml
5591+
0
5592+
SELECT ST_GeomFromWKB(x'01060000000100000001030000000100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') IS NOT NULL AS mp;
5593+
mp
5594+
0
5595+
SELECT ST_GeomFromWKB(x'01070000000100000001070000000100000001070000000100000001020000000100000000000000') IS NOT NULL AS gc;
5596+
gc
5597+
0
55865598
# End of 10.6 tests

mysql-test/main/gis.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3563,4 +3563,9 @@ set sql_mode= @orig_sql_mode;
35633563
--echo #
35643564
select st_astext(st_geomfromwkb(x'0103000000020000000400000000000000000000000000000000000000000000000000f03f0000000000000000000000000000f03f000000000000f03f0000000000000000000000000000000005000000000000000000e03f000000000000e03f')) 'no asan error here';
35653565

3566+
SELECT ST_GeomFromWKB(x'0103000000020000000400000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000000001000000') IS NOT NULL AS pg;
3567+
SELECT ST_GeomFromWKB(x'01050000000200000001020000000200000000000000000000000000000000000000000000000000F03F000000000000F03F01020000000100000000000000000000') IS NOT NULL AS ml;
3568+
SELECT ST_GeomFromWKB(x'01060000000100000001030000000100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') IS NOT NULL AS mp;
3569+
SELECT ST_GeomFromWKB(x'01070000000100000001070000000100000001070000000100000001020000000100000000000000') IS NOT NULL AS gc;
3570+
35663571
--echo # End of 10.6 tests

sql/spatial.cc

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
double my_double_round(double value, longlong dec, bool dec_unsigned,
2626
bool truncate);
2727

28+
#define advance(wkb,len,N) do { wkb+=(N); len-=(N); } while(0)
29+
2830
#ifdef HAVE_SPATIAL
2931

3032
/*
@@ -472,16 +474,17 @@ Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer,
472474

473475
if (len < WKB_HEADER_SIZE)
474476
return NULL;
475-
geom_type= wkb_get_uint(wkb+1, (wkbByteOrder)wkb[0]);
477+
wkbByteOrder bo= (wkbByteOrder)wkb[0];
478+
geom_type= wkb_get_uint(wkb+1, bo);
476479
if (!(geom= create_by_typeid(buffer, (int) geom_type)) ||
477480
res->reserve(WKB_HEADER_SIZE, 512))
478481
return NULL;
479482

480483
res->q_append((char) wkb_ndr);
481484
res->q_append(geom_type);
482485

483-
return geom->init_from_wkb(wkb + WKB_HEADER_SIZE, len - WKB_HEADER_SIZE,
484-
(wkbByteOrder) wkb[0], res) ? geom : NULL;
486+
advance(wkb,len,WKB_HEADER_SIZE);
487+
return geom->init_from_wkb(wkb, len, bo, res) ? geom : 0;
485488
}
486489

487490

@@ -1631,8 +1634,7 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
16311634

16321635
if (res->reserve(4, 512))
16331636
return 0;
1634-
wkb+= 4;
1635-
len-= 4;
1637+
advance(wkb,len,4);
16361638
res->q_append(n_linear_rings);
16371639

16381640
while (n_linear_rings--)
@@ -1649,8 +1651,7 @@ uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
16491651

16501652
if (ls.is_closed(&closed) || !closed)
16511653
return 0;
1652-
wkb+= ls_len;
1653-
len-= ls_len;
1654+
advance(wkb,len,ls_len);
16541655
}
16551656

16561657
return (uint) (wkb - wkb_orig);
@@ -2512,7 +2513,7 @@ uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len,
25122513
return 0;
25132514
res->q_append(n_line_strings);
25142515

2515-
wkb+= 4;
2516+
advance(wkb,len,4);
25162517
while (n_line_strings--)
25172518
{
25182519
Gis_line_string ls;
@@ -2524,13 +2525,12 @@ uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len,
25242525

25252526
res->q_append((char) wkb_ndr);
25262527
res->q_append((uint32) wkb_linestring);
2528+
wkbByteOrder bo= (wkbByteOrder)wkb[0];
2529+
advance(wkb,len,WKB_HEADER_SIZE);
25272530

2528-
if (!(ls_len= ls.init_from_wkb(wkb + WKB_HEADER_SIZE, len,
2529-
(wkbByteOrder) wkb[0], res)))
2531+
if (!(ls_len= ls.init_from_wkb(wkb, len, bo, res)))
25302532
return 0;
2531-
ls_len+= WKB_HEADER_SIZE;;
2532-
wkb+= ls_len;
2533-
len-= ls_len;
2533+
advance(wkb,len,ls_len);
25342534
}
25352535
return (uint) (wkb - wkb_orig);
25362536
}
@@ -2884,7 +2884,7 @@ uint Gis_multi_polygon::init_from_wkb(const char *wkb, uint len,
28842884
return 0;
28852885
res->q_append(n_poly);
28862886

2887-
wkb+=4;
2887+
advance(wkb,len,4);
28882888
while (n_poly--)
28892889
{
28902890
Gis_polygon p;
@@ -2896,12 +2896,11 @@ uint Gis_multi_polygon::init_from_wkb(const char *wkb, uint len,
28962896
res->q_append((char) wkb_ndr);
28972897
res->q_append((uint32) wkb_polygon);
28982898

2899-
if (!(p_len= p.init_from_wkb(wkb + WKB_HEADER_SIZE, len,
2900-
(wkbByteOrder) wkb[0], res)))
2899+
wkbByteOrder bo= (wkbByteOrder)wkb[0];
2900+
advance(wkb,len,WKB_HEADER_SIZE);
2901+
if (!(p_len= p.init_from_wkb(wkb, len, bo, res)))
29012902
return 0;
2902-
p_len+= WKB_HEADER_SIZE;
2903-
wkb+= p_len;
2904-
len-= p_len;
2903+
advance(wkb,len,p_len);
29052904
}
29062905
return (uint) (wkb - wkb_orig);
29072906
}
@@ -3394,7 +3393,7 @@ uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len,
33943393
return 0;
33953394
res->q_append(n_geom);
33963395

3397-
wkb+= 4;
3396+
advance(wkb,len,4);
33983397
while (n_geom--)
33993398
{
34003399
Geometry_buffer buffer;
@@ -3406,17 +3405,16 @@ uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len,
34063405
res->reserve(WKB_HEADER_SIZE, 512))
34073406
return 0;
34083407

3408+
wkbByteOrder bo= (wkbByteOrder)wkb[0];
34093409
res->q_append((char) wkb_ndr);
3410-
wkb_type= wkb_get_uint(wkb+1, (wkbByteOrder) wkb[0]);
3410+
wkb_type= wkb_get_uint(wkb+1, bo);
34113411
res->q_append(wkb_type);
34123412

3413+
advance(wkb,len,WKB_HEADER_SIZE);
34133414
if (!(geom= create_by_typeid(&buffer, wkb_type)) ||
3414-
!(g_len= geom->init_from_wkb(wkb + WKB_HEADER_SIZE, len,
3415-
(wkbByteOrder) wkb[0], res)))
3415+
!(g_len= geom->init_from_wkb(wkb, len, bo, res)))
34163416
return 0;
3417-
g_len+= WKB_HEADER_SIZE;
3418-
wkb+= g_len;
3419-
len-= g_len;
3417+
advance(wkb,len,g_len);
34203418
}
34213419
return (uint) (wkb - wkb_orig);
34223420
}

0 commit comments

Comments
 (0)