Commit 3c358724 authored by Georgi Kodinov's avatar Georgi Kodinov

merge 5.1->5.5

parents accc5d92 0f31bfea
/* /*
Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -377,13 +377,19 @@ const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data, ...@@ -377,13 +377,19 @@ const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
uint offset) const uint offset) const
{ {
uint32 points; uint32 points;
size_t points_available;
/* read number of points */ /* read number of points */
if (no_data(data, 4)) if (no_data(data, 4))
return 0; return 0;
points= uint4korr(data); points= uint4korr(data);
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points)) /* can't use any of the helper functions due to the offset */
points_available=
data <= m_data_end ?
(m_data_end - data) / (POINT_DATA_SIZE + offset) : 0;
if (points_available < points)
return 0; return 0;
/* Calculate MBR for points */ /* Calculate MBR for points */
...@@ -539,7 +545,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const ...@@ -539,7 +545,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
data += 4; data += 4;
if (n_points < 1 || if (n_points < 1 ||
no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) || not_enough_points(data, n_points) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points)) txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points))
return 1; return 1;
...@@ -576,7 +582,7 @@ int Gis_line_string::geom_length(double *len) const ...@@ -576,7 +582,7 @@ int Gis_line_string::geom_length(double *len) const
return 1; return 1;
n_points= uint4korr(data); n_points= uint4korr(data);
data+= 4; data+= 4;
if (n_points < 1 || no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) if (n_points < 1 || not_enough_points(data, n_points))
return 1; return 1;
get_point(&prev_x, &prev_y, data); get_point(&prev_x, &prev_y, data);
...@@ -610,8 +616,7 @@ int Gis_line_string::is_closed(int *closed) const ...@@ -610,8 +616,7 @@ int Gis_line_string::is_closed(int *closed) const
return 0; return 0;
} }
data+= 4; data+= 4;
if (n_points == 0 || if (n_points == 0 || not_enough_points(data, n_points))
no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
return 1; return 1;
/* Get first point */ /* Get first point */
...@@ -780,7 +785,8 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const ...@@ -780,7 +785,8 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1; return 1;
n_points= uint4korr(data); n_points= uint4korr(data);
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) ||
if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1; return 1;
txt->qs_append('('); txt->qs_append('(');
...@@ -834,7 +840,7 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const ...@@ -834,7 +840,7 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
if (no_data(data, 4)) if (no_data(data, 4))
return 1; return 1;
n_points= uint4korr(data); n_points= uint4korr(data);
if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) if (not_enough_points(data, n_points))
return 1; return 1;
get_point(&prev_x, &prev_y, data+4); get_point(&prev_x, &prev_y, data+4);
data+= (4+SIZEOF_STORED_DOUBLE*2); data+= (4+SIZEOF_STORED_DOUBLE*2);
...@@ -870,7 +876,7 @@ int Gis_polygon::exterior_ring(String *result) const ...@@ -870,7 +876,7 @@ int Gis_polygon::exterior_ring(String *result) const
n_points= uint4korr(data); n_points= uint4korr(data);
data+= 4; data+= 4;
length= n_points * POINT_DATA_SIZE; length= n_points * POINT_DATA_SIZE;
if (no_data(data, length) || result->reserve(1+4+4+ length)) if (not_enough_points(data, n_points) || result->reserve(1+4+4+ length))
return 1; return 1;
result->q_append((char) wkb_ndr); result->q_append((char) wkb_ndr);
...@@ -916,7 +922,7 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const ...@@ -916,7 +922,7 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
n_points= uint4korr(data); n_points= uint4korr(data);
points_size= n_points * POINT_DATA_SIZE; points_size= n_points * POINT_DATA_SIZE;
data+= 4; data+= 4;
if (no_data(data, points_size) || result->reserve(1+4+4+ points_size)) if (not_enough_points(data, n_points) || result->reserve(1+4+4+ points_size))
return 1; return 1;
result->q_append((char) wkb_ndr); result->q_append((char) wkb_ndr);
...@@ -955,7 +961,7 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -955,7 +961,7 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
return 1; return 1;
org_n_points= n_points= uint4korr(data); org_n_points= n_points= uint4korr(data);
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points)) if (not_enough_points(data, n_points))
return 1; return 1;
get_point(&prev_x, &prev_y, data); get_point(&prev_x, &prev_y, data);
data+= (SIZEOF_STORED_DOUBLE*2); data+= (SIZEOF_STORED_DOUBLE*2);
...@@ -1080,15 +1086,22 @@ uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, ...@@ -1080,15 +1086,22 @@ uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo,
bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
{ {
uint32 n_points; uint32 n_points;
if (no_data(m_data, 4)) size_t points_available;
const char *data= m_data;
if (no_data(data, 4))
return 1; return 1;
n_points= uint4korr(m_data); n_points= uint4korr(data);
if (no_data(m_data+4, data+= 4;
n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) || points_available= data <= m_data_end ?
(m_data_end - data) / (POINT_DATA_SIZE + WKB_HEADER_SIZE) : 0;
/* can't use any of the helper functions due to WKB_HEADER_SIZE */
if (n_points > points_available ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1; return 1;
*end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE); *end= append_points(txt, n_points, data, WKB_HEADER_SIZE);
txt->length(txt->length()-1); // Remove end ',' txt->length(txt->length()-1); // Remove end ','
return 0; return 0;
} }
...@@ -1242,7 +1255,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt, ...@@ -1242,7 +1255,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt,
return 1; return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE); n_points= uint4korr(data + WKB_HEADER_SIZE);
data+= WKB_HEADER_SIZE + 4; data+= WKB_HEADER_SIZE + 4;
if (no_data(data, n_points * (SIZEOF_STORED_DOUBLE*2)) || if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points)) txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1; return 1;
txt->qs_append('('); txt->qs_append('(');
...@@ -1302,8 +1315,8 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const ...@@ -1302,8 +1315,8 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
if (no_data(data, WKB_HEADER_SIZE + 4)) if (no_data(data, WKB_HEADER_SIZE + 4))
return 1; return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE); n_points= uint4korr(data + WKB_HEADER_SIZE);
length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points; length= WKB_HEADER_SIZE + 4 + POINT_DATA_SIZE * n_points;
if (no_data(data, length)) if (not_enough_points(data + WKB_HEADER_SIZE + 4, n_points))
return 1; return 1;
if (!--num) if (!--num)
break; break;
...@@ -1503,7 +1516,7 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const ...@@ -1503,7 +1516,7 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1; return 1;
uint32 n_points= uint4korr(data); uint32 n_points= uint4korr(data);
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE * 2) * n_points) || if (not_enough_points(data, n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points, txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
512)) 512))
return 1; return 1;
......
/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -25,7 +25,7 @@ class Gis_read_stream; ...@@ -25,7 +25,7 @@ class Gis_read_stream;
const uint SRID_SIZE= 4; const uint SRID_SIZE= 4;
const uint SIZEOF_STORED_DOUBLE= 8; const uint SIZEOF_STORED_DOUBLE= 8;
const uint POINT_DATA_SIZE= SIZEOF_STORED_DOUBLE*2; const uint POINT_DATA_SIZE= (SIZEOF_STORED_DOUBLE * 2);
const uint WKB_HEADER_SIZE= 1+4; const uint WKB_HEADER_SIZE= 1+4;
const uint32 GET_SIZE_ERROR= ((uint32) -1); const uint32 GET_SIZE_ERROR= ((uint32) -1);
...@@ -321,10 +321,33 @@ protected: ...@@ -321,10 +321,33 @@ protected:
const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset) const char *get_mbr_for_points(MBR *mbr, const char *data, uint offset)
const; const;
inline bool no_data(const char *cur_data, uint32 data_amount) const /**
Check if there're enough data remaining as requested
@arg cur_data pointer to the position in the binary form
@arg data_amount number of points expected
@return true if not enough data
*/
inline bool no_data(const char *cur_data, size_t data_amount) const
{ {
return (cur_data + data_amount > m_data_end); return (cur_data + data_amount > m_data_end);
} }
/**
Check if there're enough points remaining as requested
Need to perform the calculation in logical units, since multiplication
can overflow the size data type.
@arg data pointer to the begining of the points array
@arg expected_points number of points expected
@return true if there are not enough points
*/
inline bool not_enough_points(const char *data, uint32 expected_points) const
{
return (m_data_end < data ||
(expected_points > ((m_data_end - data) / POINT_DATA_SIZE)));
}
const char *m_data; const char *m_data;
const char *m_data_end; const char *m_data_end;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment