components/mysql-5-1/patches/bug68591.patch
branchs11-update
changeset 2680 70e041ba5b04
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/mysql-5-1/patches/bug68591.patch	Wed Jul 17 00:17:02 2013 -0700
@@ -0,0 +1,287 @@
+# Fixes Solaris bug #15688738
+# ===========================
+
+--- sql/spatial.h	revid:[email protected]
++++ sql/spatial.h	2013-06-26 05:14:10 +0000
+@@ -324,6 +324,26 @@
+   {
+     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
++     @arg extra_point_space extra space for each point element in the array
++     @return               true if there are not enough points
++  */
++  inline bool not_enough_points(const char *data, uint32 expected_points,
++                                uint32 extra_point_space = 0) const
++  {
++    return (m_data_end < data ||
++            (expected_points > ((m_data_end - data) /
++                                (POINT_DATA_SIZE + extra_point_space))));
++  }
++
+   const char *m_data;
+   const char *m_data_end;
+ };
+
+=== modified file 'sql/spatial.cc'
+--- sql/spatial.cc	revid:[email protected]
++++ sql/spatial.cc	2013-06-26 05:14:10 +0000
+@@ -393,7 +393,7 @@
+   points= uint4korr(data);
+   data+= 4;
+ 
+-  if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points))
++  if (not_enough_points(data, points, offset))
+     return 0;
+ 
+   /* Calculate MBR for points */
+@@ -476,9 +476,16 @@
+ 
+ uint32 Gis_line_string::get_data_size() const 
+ {
++  size_t n_points;
+   if (no_data(m_data, 4))
+     return GET_SIZE_ERROR;
+-  return 4 + uint4korr(m_data) * POINT_DATA_SIZE;
++
++  n_points= uint4korr(m_data);
++
++  if (not_enough_points(m_data + 4, n_points))
++    return GET_SIZE_ERROR;
++
++  return 4 + n_points * POINT_DATA_SIZE;
+ }
+ 
+ 
+@@ -548,7 +555,7 @@
+   data += 4;
+ 
+   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))
+     return 1;
+ 
+@@ -585,7 +592,7 @@
+     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 || not_enough_points(data, n_points))
+     return 1;
+ 
+   get_point(&prev_x, &prev_y, data);
+@@ -619,7 +626,7 @@
+     return 0;
+   }
+   data+= 4;
+-  if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
++  if (n_points == 0 || not_enough_points(data, n_points))
+     return 1;
+ 
+   /* Get first point */
+@@ -690,9 +697,16 @@
+ 
+   while (n_linear_rings--)
+   {
++    size_t n_points;
+     if (no_data(data, 4))
+       return GET_SIZE_ERROR;
+-    data+= 4 + uint4korr(data)*POINT_DATA_SIZE;
++    n_points= uint4korr(data);
++    data+= 4;
++
++    if (not_enough_points(data, n_points))
++      return GET_SIZE_ERROR;
++
++    data+= n_points * POINT_DATA_SIZE;
+   }
+   return (uint32) (data - m_data);
+ }
+@@ -786,8 +800,9 @@
+       return 1;
+     n_points= uint4korr(data);
+     data+= 4;
+-    if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points) ||
+-	txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
++
++    if (not_enough_points(data, n_points) ||
++        txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
+       return 1;
+     txt->qs_append('(');
+     data= append_points(txt, n_points, data, 0);
+@@ -840,7 +855,7 @@
+     if (no_data(data, 4))
+       return 1;
+     n_points= uint4korr(data);
+-    if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
++    if (not_enough_points(data, n_points))
+       return 1;
+     get_point(&prev_x, &prev_y, data+4);
+     data+= (4+SIZEOF_STORED_DOUBLE*2);
+@@ -876,7 +891,7 @@
+   n_points= uint4korr(data);
+   data+= 4;
+   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;
+ 
+   result->q_append((char) wkb_ndr);
+@@ -922,7 +937,7 @@
+   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 (not_enough_points(data, n_points) || result->reserve(1+4+4+ points_size))
+     return 1;
+ 
+   result->q_append((char) wkb_ndr);
+@@ -964,7 +979,7 @@
+       return 1;
+     org_n_points= n_points= uint4korr(data);
+     data+= 4;
+-    if (no_data(data, (SIZEOF_STORED_DOUBLE*2) * n_points))
++    if (not_enough_points(data, n_points))
+       return 1;
+     get_point(&prev_x, &prev_y, data);
+     data+= (SIZEOF_STORED_DOUBLE*2);
+@@ -1021,14 +1036,21 @@
+ 
+ /***************************** MultiPoint *******************************/
+ 
+-uint32 Gis_multi_point::get_data_size() const 
++uint32 Gis_multi_point::get_data_size() const
+ {
++  size_t n_points;
++
+   if (no_data(m_data, 4))
+     return GET_SIZE_ERROR;
+-  return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE);
++
++  n_points= uint4korr(m_data);
++
++  if (not_enough_points(m_data + 4, n_points, WKB_HEADER_SIZE))
++    return GET_SIZE_ERROR;
++
++  return 4 + n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE);
+ }
+ 
+-
+ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb)
+ {
+   uint32 n_points= 0;
+@@ -1085,24 +1107,26 @@
+   return proper_size;
+ }
+ 
+-
+ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
+ {
+   uint32 n_points;
+-  if (no_data(m_data, 4))
++  const char *data= m_data;
++
++  if (no_data(data, 4))
+     return 1;
+ 
+-  n_points= uint4korr(m_data);
+-  if (no_data(m_data+4,
+-	      n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) ||
++  n_points= uint4korr(data);
++  data+= 4;
++
++  if (not_enough_points(data, n_points, WKB_HEADER_SIZE) ||
+       txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
+     return 1;
+-  *end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE);
+-  txt->length(txt->length()-1);			// Remove end ','
++
++  *end= append_points(txt, n_points, data, WKB_HEADER_SIZE);
++  txt->length(txt->length()-1);                 // Remove end ','
+   return 0;
+ }
+ 
+-
+ bool Gis_multi_point::get_mbr(MBR *mbr, const char **end) const
+ {
+   return (*end= get_mbr_for_points(mbr, m_data, WKB_HEADER_SIZE)) == 0;
+@@ -1155,11 +1179,20 @@
+ 
+   while (n_line_strings--)
+   {
++    size_t n_points;
++
+     if (no_data(data, WKB_HEADER_SIZE + 4))
+       return GET_SIZE_ERROR;
+-    data+= (WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) *
+-	    POINT_DATA_SIZE);
++
++    n_points= uint4korr(data + WKB_HEADER_SIZE);
++    data+= WKB_HEADER_SIZE + 4;
++
++    if (not_enough_points(data, n_points))
++      return GET_SIZE_ERROR;
++
++    data+= n_points * POINT_DATA_SIZE;
+   }
++
+   return (uint32) (data - m_data);
+ }
+ 
+@@ -1251,7 +1284,7 @@
+       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 (not_enough_points(data, n_points) ||
+ 	txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
+       return 1;
+     txt->qs_append('(');
+@@ -1312,7 +1345,7 @@
+       return 1;
+     n_points= uint4korr(data + WKB_HEADER_SIZE);
+     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;
+     if (!--num)
+       break;
+@@ -1410,9 +1443,16 @@
+ 
+     while (n_linear_rings--)
+     {
++      size_t n_points;
+       if (no_data(data, 4))
+-	return GET_SIZE_ERROR;
+-      data+= 4 + uint4korr(data) * POINT_DATA_SIZE;
++        return GET_SIZE_ERROR;
++      n_points= uint4korr(data);
++      data+= 4;
++
++      if (not_enough_points(data, n_points))
++        return GET_SIZE_ERROR;
++
++      data+= n_points * POINT_DATA_SIZE;
+     }
+   }
+   return (uint32) (data - m_data);
+@@ -1512,7 +1552,7 @@
+         return 1;
+       uint32 n_points= uint4korr(data);
+       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,
+ 		       512))
+ 	return 1;
+
+=== modified file 'sql/spatial.h'