diff -up mysql-5.5.31/mysql-test/r/gis.result.cve mysql-5.5.31/mysql-test/r/gis.result --- mysql-5.5.31/mysql-test/r/gis.result.cve 2013-06-03 16:32:33.732025515 +0200 +++ mysql-5.5.31/mysql-test/r/gis.result 2013-06-03 16:34:04.519691044 +0200 @@ -1113,4 +1113,19 @@ SELECT 1 FROM g1 WHERE a >= ANY (SELECT 1 FROM g1 WHERE a = geomfromtext('') OR a) ; 1 DROP TABLE g1; +# +# TODO-424 geometry query crashes server +# +select astext(0x0100000000030000000100000000000010); +astext(0x0100000000030000000100000000000010) +NULL +select area(0x0100000000030000000100000000000010); +area(0x0100000000030000000100000000000010) +NULL +select astext(exteriorring(0x0100000000030000000100000000000010)); +astext(exteriorring(0x0100000000030000000100000000000010)) +NULL +select astext(centroid(0x0100000000030000000100000000000010)); +astext(centroid(0x0100000000030000000100000000000010)) +NULL End of 5.5 tests diff -up mysql-5.5.31/mysql-test/t/gis.test.cve mysql-5.5.31/mysql-test/t/gis.test --- mysql-5.5.31/mysql-test/t/gis.test.cve 2013-06-03 16:32:33.733025512 +0200 +++ mysql-5.5.31/mysql-test/t/gis.test 2013-06-03 16:34:38.942560749 +0200 @@ -868,4 +868,11 @@ SELECT 1 FROM g1 WHERE a >= ANY DROP TABLE g1; +--echo # +--echo # TODO-424 geometry query crashes server +--echo # +select astext(0x0100000000030000000100000000000010); +select area(0x0100000000030000000100000000000010); +select astext(exteriorring(0x0100000000030000000100000000000010)); +select astext(centroid(0x0100000000030000000100000000000010)); --echo End of 5.5 tests diff -up mysql-5.5.31/sql/spatial.cc.cve mysql-5.5.31/sql/spatial.cc --- mysql-5.5.31/sql/spatial.cc.cve 2013-03-25 14:14:58.000000000 +0100 +++ mysql-5.5.31/sql/spatial.cc 2013-06-03 16:45:52.790665557 +0200 @@ -538,7 +538,7 @@ bool Gis_line_string::get_data_as_wkt(St n_points= uint4korr(data); data += 4; - if (n_points < 1 || + if (n_points < 1 || n_points > max_n_points || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) || txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) return 1; @@ -576,7 +576,8 @@ int Gis_line_string::geom_length(double return 1; n_points= uint4korr(data); data+= 4; - if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + if (n_points < 1 || n_points > max_n_points || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; get_point(&prev_x, &prev_y, data); @@ -610,7 +611,7 @@ int Gis_line_string::is_closed(int *clos return 0; } data+= 4; - if (n_points == 0 || + if (n_points == 0 || n_points > max_n_points || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; @@ -780,7 +781,7 @@ bool Gis_polygon::get_data_as_wkt(String return 1; n_points= uint4korr(data); data+= 4; - if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) || + if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) || txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) return 1; txt->qs_append('('); @@ -834,7 +835,7 @@ int Gis_polygon::area(double *ar, const if (no_data(data, 4)) return 1; n_points= uint4korr(data); - if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) + if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) return 1; get_point(&prev_x, &prev_y, data+4); data+= (4+SIZEOF_STORED_DOUBLE*2); @@ -870,7 +871,8 @@ int Gis_polygon::exterior_ring(String *r n_points= uint4korr(data); data+= 4; length= n_points * POINT_DATA_SIZE; - if (no_data(data, length) || result->reserve(1+4+4+ length)) + if (n_points > max_n_points || + no_data(data, length) || result->reserve(1+4+4+ length)) return 1; result->q_append((char) wkb_ndr); @@ -916,7 +918,8 @@ int Gis_polygon::interior_ring_n(uint32 n_points= uint4korr(data); points_size= n_points * POINT_DATA_SIZE; data+= 4; - if (no_data(data, points_size) || result->reserve(1+4+4+ points_size)) + if (n_points > max_n_points || + no_data(data, points_size) || result->reserve(1+4+4+ points_size)) return 1; result->q_append((char) wkb_ndr); @@ -955,7 +958,7 @@ int Gis_polygon::centroid_xy(double *x, return 1; org_n_points= n_points= uint4korr(data); data+= 4; - if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) + if (n_points > max_n_points || no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) return 1; get_point(&prev_x, &prev_y, data); data+= (SIZEOF_STORED_DOUBLE*2); @@ -1242,7 +1245,7 @@ bool Gis_multi_line_string::get_data_as_ return 1; n_points= uint4korr(data + WKB_HEADER_SIZE); data+= WKB_HEADER_SIZE + 4; - if (no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || + if (n_points > max_n_points || no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) return 1; txt->qs_append('('); @@ -1503,7 +1506,8 @@ bool Gis_multi_polygon::get_data_as_wkt( return 1; uint32 n_points= uint4korr(data); data+= 4; - if (no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || + if (n_points > max_n_points || + no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points, 512)) return 1; @@ -1586,6 +1590,8 @@ int Gis_multi_polygon::geometry_n(uint32 if (no_data(data, 4)) return 1; n_points= uint4korr(data); + if (n_points > max_n_points) + return 1; data+= 4 + POINT_DATA_SIZE * n_points; } } while (--num); diff -up mysql-5.5.31/sql/spatial.h.cve mysql-5.5.31/sql/spatial.h --- mysql-5.5.31/sql/spatial.h.cve 2013-03-25 14:14:58.000000000 +0100 +++ mysql-5.5.31/sql/spatial.h 2013-06-03 16:32:33.737025500 +0200 @@ -200,6 +200,11 @@ struct Geometry_buffer; class Geometry { public: + // Maximum number of points in feature that can fit into String + static const uint32 max_n_points= + (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / + POINT_DATA_SIZE; + Geometry() {} /* Remove gcc warning */ virtual ~Geometry() {} /* Remove gcc warning */ static void *operator new(size_t size, void *buffer) @@ -383,10 +388,6 @@ public: class Gis_line_string: public Geometry { - // Maximum number of points in LineString that can fit into String - static const uint32 max_n_points= - (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / - POINT_DATA_SIZE; public: Gis_line_string() {} /* Remove gcc warning */ virtual ~Gis_line_string() {} /* Remove gcc warning */