Commit 48be80cd authored by Sergei Golubchik's avatar Sergei Golubchik

5.1 merge

parents 5dec570d e70ce465
...@@ -184,7 +184,20 @@ SELECT member_id_to, COUNT(*) FROM t1 WHERE r_date = ...@@ -184,7 +184,20 @@ SELECT member_id_to, COUNT(*) FROM t1 WHERE r_date =
member_id_to COUNT(*) member_id_to COUNT(*)
518491 5 518491 5
DROP TABLE t1; DROP TABLE t1;
# End of test BUG#12713907 #
# MDEV-4269: crash when grouping by values()
#
SELECT @@storage_engine INTO @old_engine;
set storage_engine=innodb;
create table y select 1 b;
select 1 from y group by b;
1
1
select 1 from y group by values(b);
1
1
drop table y;
SET storage_engine=@old_engine;
# #
# Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN # Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN
# #
......
...@@ -2646,4 +2646,11 @@ NULL ...@@ -2646,4 +2646,11 @@ NULL
SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?');
LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?') LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?')
NULL NULL
create table t1 (i int);
insert into t1 values (null),(8);
select group_concat( i ), make_set( i, 'a', 'b' ) field from t1 group by field;
group_concat( i ) field
NULL NULL
8
drop table t1;
End of 5.1 tests End of 5.1 tests
...@@ -1087,4 +1087,31 @@ NULL ...@@ -1087,4 +1087,31 @@ NULL
# #
SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); SELECT GEOMETRYCOLLECTION((SELECT @@OLD));
ERROR 22007: Illegal non geometric '' value found during parsing ERROR 22007: Illegal non geometric '' value found during parsing
#
# MDEV-4252 geometry query crashes server
#
select astext(0x0100000000030000000100000000000010);
astext(0x0100000000030000000100000000000010)
NULL
select envelope(0x0100000000030000000100000000000010);
envelope(0x0100000000030000000100000000000010)
NULL
select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1);
geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1)
NULL
select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1);
geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1)
NULL
#
# MDEV-4296 Assertion `n_linear_rings > 0' fails in Gis_polygon::centroid_xy
#
SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) )));
Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) )))
NULL
#
# MDEV-4295 Server crashes in get_point on a query with Area, AsBinary, MultiPoint
#
SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2))));
Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2))))
NULL
End of 5.1 tests End of 5.1 tests
...@@ -126,7 +126,20 @@ SELECT member_id_to, COUNT(*) FROM t1 WHERE r_date = ...@@ -126,7 +126,20 @@ SELECT member_id_to, COUNT(*) FROM t1 WHERE r_date =
DROP TABLE t1; DROP TABLE t1;
--echo # End of test BUG#12713907 --echo #
--echo # MDEV-4269: crash when grouping by values()
--echo #
SELECT @@storage_engine INTO @old_engine;
set storage_engine=innodb;
create table y select 1 b;
select 1 from y group by b;
select 1 from y group by values(b);
drop table y;
SET storage_engine=@old_engine;
### End of 5.1 tests
--echo # --echo #
--echo # Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN --echo # Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN
...@@ -140,3 +153,6 @@ SELECT MIN(c) FROM t1 GROUP BY b; ...@@ -140,3 +153,6 @@ SELECT MIN(c) FROM t1 GROUP BY b;
EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b;
DROP TABLE t1; DROP TABLE t1;
### End of 5.2 tests
...@@ -1390,5 +1390,12 @@ SELECT REPEAT('1', DAY(FROM_UNIXTIME(-1))); ...@@ -1390,5 +1390,12 @@ SELECT REPEAT('1', DAY(FROM_UNIXTIME(-1)));
SELECT RPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); SELECT RPAD('hi', DAY(FROM_UNIXTIME(-1)),'?');
SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?'); SELECT LPAD('hi', DAY(FROM_UNIXTIME(-1)),'?');
#
# MDEV-4289 Assertion `0' fails in make_sortkey with GROUP_CONCAT, MAKE_SET, GROUP BY
#
create table t1 (i int);
insert into t1 values (null),(8);
select group_concat( i ), make_set( i, 'a', 'b' ) field from t1 group by field;
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -826,5 +826,22 @@ SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); ...@@ -826,5 +826,22 @@ SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20)));
--error ER_ILLEGAL_VALUE_FOR_TYPE --error ER_ILLEGAL_VALUE_FOR_TYPE
SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); SELECT GEOMETRYCOLLECTION((SELECT @@OLD));
--echo #
--echo # MDEV-4252 geometry query crashes server
--echo #
select astext(0x0100000000030000000100000000000010);
select envelope(0x0100000000030000000100000000000010);
select geometryn(0x0100000000070000000100000001030000000200000000000000ffff0000, 1);
select geometryn(0x0100000000070000000100000001030000000200000000000000ffffff0f, 1);
--echo #
--echo # MDEV-4296 Assertion `n_linear_rings > 0' fails in Gis_polygon::centroid_xy
--echo #
SELECT Centroid( AsBinary( LineString(Point(0,0), Point(0,0), Point(0,0) )));
--echo #
--echo # MDEV-4295 Server crashes in get_point on a query with Area, AsBinary, MultiPoint
--echo #
SELECT Area(AsBinary(MultiPoint(Point(0,9), Point(0,1), Point(2,2))));
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -3952,8 +3952,7 @@ Create_func_make_set::create_native(THD *thd, LEX_STRING name, ...@@ -3952,8 +3952,7 @@ Create_func_make_set::create_native(THD *thd, LEX_STRING name,
return NULL; return NULL;
} }
Item *param_1= item_list->pop(); return new (thd->mem_root) Item_func_make_set(*item_list);
return new (thd->mem_root) Item_func_make_set(param_1, *item_list);
} }
......
...@@ -2233,37 +2233,14 @@ String *Item_func_elt::val_str(String *str) ...@@ -2233,37 +2233,14 @@ String *Item_func_elt::val_str(String *str)
} }
void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields)
{
item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE);
Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
}
void Item_func_make_set::fix_length_and_dec() void Item_func_make_set::fix_length_and_dec()
{ {
max_length=arg_count-1; if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV, 1))
if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
return; return;
for (uint i=0 ; i < arg_count ; i++) max_length=arg_count-2;
for (uint i=1 ; i < arg_count ; i++)
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
used_tables_cache|= item->used_tables();
not_null_tables_cache&= item->not_null_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
void Item_func_make_set::update_used_tables()
{
Item_func::update_used_tables();
item->update_used_tables();
used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item();
} }
...@@ -2272,15 +2249,15 @@ String *Item_func_make_set::val_str(String *str) ...@@ -2272,15 +2249,15 @@ String *Item_func_make_set::val_str(String *str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
ulonglong bits; ulonglong bits;
bool first_found=0; bool first_found=0;
Item **ptr=args; Item **ptr=args+1;
String *result=&my_empty_string; String *result=&my_empty_string;
bits=item->val_int(); bits=args[0]->val_int();
if ((null_value=item->null_value)) if ((null_value=args[0]->null_value))
return NULL; return NULL;
if (arg_count < 64) if (arg_count < 65)
bits &= ((ulonglong) 1 << arg_count)-1; bits &= ((ulonglong) 1 << (arg_count-1))-1;
for (; bits; bits >>= 1, ptr++) for (; bits; bits >>= 1, ptr++)
{ {
...@@ -2320,39 +2297,6 @@ String *Item_func_make_set::val_str(String *str) ...@@ -2320,39 +2297,6 @@ String *Item_func_make_set::val_str(String *str)
} }
Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg)
{
DBUG_ASSERT(!current_thd->is_stmt_prepare());
Item *new_item= item->transform(transformer, arg);
if (!new_item)
return 0;
/*
THD::change_item_tree() should be called only if the tree was
really transformed, i.e. when a new item has been created.
Otherwise we'll be allocating a lot of unnecessary memory for
change records at each execution.
*/
if (item != new_item)
current_thd->change_item_tree(&item, new_item);
return Item_str_func::transform(transformer, arg);
}
void Item_func_make_set::print(String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN("make_set("));
item->print(str, query_type);
if (arg_count)
{
str->append(',');
print_args(str, 0, query_type);
}
str->append(')');
}
String *Item_func_char::val_str(String *str) String *Item_func_char::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
......
...@@ -506,31 +506,13 @@ public: ...@@ -506,31 +506,13 @@ public:
class Item_func_make_set :public Item_str_func class Item_func_make_set :public Item_str_func
{ {
Item *item;
String tmp_str; String tmp_str;
public: public:
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} Item_func_make_set(List<Item> &list) :Item_str_func(list) {}
String *val_str(String *str); String *val_str(String *str);
bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
return ((!item->fixed && item->fix_fields(thd, &item)) ||
item->check_cols(1) ||
Item_func::fix_fields(thd, ref));
}
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "make_set"; } const char *func_name() const { return "make_set"; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
return item->walk(processor, walk_subquery, arg) ||
Item_str_func::walk(processor, walk_subquery, arg);
}
Item *transform(Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
}; };
......
...@@ -394,18 +394,19 @@ const char *Geometry::append_points(String *txt, uint32 n_points, ...@@ -394,18 +394,19 @@ const char *Geometry::append_points(String *txt, uint32 n_points,
const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data, const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
uint offset) const uint offset) const
{ {
uint32 points; uint32 n_points;
/* 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); n_points= uint4korr(data);
data+= 4; data+= 4;
if (no_data(data, (SIZEOF_STORED_DOUBLE * 2 + offset) * points)) if (n_points > max_n_points ||
no_data(data, (POINT_DATA_SIZE + offset) * n_points))
return 0; return 0;
/* Calculate MBR for points */ /* Calculate MBR for points */
while (points--) while (n_points--)
{ {
data+= offset; data+= offset;
mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE); mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE);
...@@ -484,9 +485,12 @@ const Geometry::Class_info *Gis_point::get_class_info() const ...@@ -484,9 +485,12 @@ const Geometry::Class_info *Gis_point::get_class_info() const
uint32 Gis_line_string::get_data_size() const uint32 Gis_line_string::get_data_size() const
{ {
if (no_data(m_data, 4)) uint32 n_points, size;
if (no_data(m_data, 4) ||
(n_points= uint4korr(m_data)) > max_n_points ||
no_data(m_data, (size= 4 + n_points * POINT_DATA_SIZE)))
return GET_SIZE_ERROR; return GET_SIZE_ERROR;
return 4 + uint4korr(m_data) * POINT_DATA_SIZE; return size;
} }
...@@ -556,7 +560,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const ...@@ -556,7 +560,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
n_points= uint4korr(data); n_points= uint4korr(data);
data += 4; data += 4;
if (n_points < 1 || if (n_points < 1 || n_points > max_n_points ||
no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points) || no_data(data, SIZEOF_STORED_DOUBLE * 2 * 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;
...@@ -594,7 +598,8 @@ int Gis_line_string::geom_length(double *len) const ...@@ -594,7 +598,8 @@ 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 || n_points > max_n_points ||
no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
return 1; return 1;
get_point(&prev_x, &prev_y, data); get_point(&prev_x, &prev_y, data);
...@@ -628,7 +633,7 @@ int Gis_line_string::is_closed(int *closed) const ...@@ -628,7 +633,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 || n_points > max_n_points ||
no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
return 1; return 1;
...@@ -664,6 +669,9 @@ int Gis_line_string::end_point(String *result) const ...@@ -664,6 +669,9 @@ int Gis_line_string::end_point(String *result) const
if (no_data(m_data, 4)) if (no_data(m_data, 4))
return 1; return 1;
n_points= uint4korr(m_data); n_points= uint4korr(m_data);
if (n_points == 0 || n_points > max_n_points ||
no_data(m_data, POINT_DATA_SIZE * n_points))
return 1;
return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE); return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE);
} }
...@@ -673,11 +681,14 @@ int Gis_line_string::point_n(uint32 num, String *result) const ...@@ -673,11 +681,14 @@ int Gis_line_string::point_n(uint32 num, String *result) const
uint32 n_points; uint32 n_points;
if (no_data(m_data, 4)) if (no_data(m_data, 4))
return 1; return 1;
num--;
n_points= uint4korr(m_data); n_points= uint4korr(m_data);
if ((uint32) (num - 1) >= n_points) // means (num > n_points || num < 1) if (num >= n_points ||
num > max_n_points || // means (num > n_points || num < 1)
no_data(m_data, num * POINT_DATA_SIZE))
return 1; return 1;
return create_point(result, m_data + 4 + (num - 1) * POINT_DATA_SIZE); return create_point(result, m_data + 4 + num*POINT_DATA_SIZE);
} }
const Geometry::Class_info *Gis_line_string::get_class_info() const const Geometry::Class_info *Gis_line_string::get_class_info() const
...@@ -691,6 +702,7 @@ const Geometry::Class_info *Gis_line_string::get_class_info() const ...@@ -691,6 +702,7 @@ const Geometry::Class_info *Gis_line_string::get_class_info() const
uint32 Gis_polygon::get_data_size() const uint32 Gis_polygon::get_data_size() const
{ {
uint32 n_linear_rings; uint32 n_linear_rings;
uint32 n_points;
const char *data= m_data; const char *data= m_data;
if (no_data(data, 4)) if (no_data(data, 4))
...@@ -700,10 +712,13 @@ uint32 Gis_polygon::get_data_size() const ...@@ -700,10 +712,13 @@ uint32 Gis_polygon::get_data_size() const
while (n_linear_rings--) while (n_linear_rings--)
{ {
if (no_data(data, 4)) if (no_data(data, 4) ||
(n_points= uint4korr(data)) > max_n_points)
return GET_SIZE_ERROR; return GET_SIZE_ERROR;
data+= 4 + uint4korr(data)*POINT_DATA_SIZE; data+= 4 + n_points*POINT_DATA_SIZE;
} }
if (no_data(data, 0))
return GET_SIZE_ERROR;
return (uint32) (data - m_data); return (uint32) (data - m_data);
} }
...@@ -798,7 +813,8 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const ...@@ -798,7 +813,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 (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)) txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1; return 1;
txt->qs_append('('); txt->qs_append('(');
...@@ -852,7 +868,8 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const ...@@ -852,7 +868,8 @@ 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 (n_points == 0 || n_points > max_n_points ||
no_data(data, (SIZEOF_STORED_DOUBLE*2) * 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);
...@@ -888,7 +905,8 @@ int Gis_polygon::exterior_ring(String *result) const ...@@ -888,7 +905,8 @@ 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 (n_points > max_n_points ||
no_data(data, length) || result->reserve(1+4+4+ length))
return 1; return 1;
result->q_append((char) wkb_ndr); result->q_append((char) wkb_ndr);
...@@ -954,13 +972,11 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -954,13 +972,11 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
const char *data= m_data; const char *data= m_data;
bool first_loop= 1; bool first_loop= 1;
if (no_data(data, 4)) if (no_data(data, 4) ||
(n_linear_rings= uint4korr(data)) == 0)
return 1; return 1;
n_linear_rings= uint4korr(data);
data+= 4; data+= 4;
DBUG_ASSERT(n_linear_rings > 0);
while (n_linear_rings--) while (n_linear_rings--)
{ {
uint32 n_points, org_n_points; uint32 n_points, org_n_points;
...@@ -973,7 +989,8 @@ int Gis_polygon::centroid_xy(double *x, double *y) const ...@@ -973,7 +989,8 @@ 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 (n_points == 0 || n_points > max_n_points ||
no_data(data, (SIZEOF_STORED_DOUBLE*2) * 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);
...@@ -1032,9 +1049,14 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const ...@@ -1032,9 +1049,14 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const
uint32 Gis_multi_point::get_data_size() const uint32 Gis_multi_point::get_data_size() const
{ {
if (no_data(m_data, 4)) uint32 n_points;
return GET_SIZE_ERROR; uint32 size;
return 4 + uint4korr(m_data)*(POINT_DATA_SIZE + WKB_HEADER_SIZE);
if (no_data(m_data, 4) ||
(n_points= uint4korr(m_data)) > max_n_points ||
no_data(m_data, (size= 4 + n_points*(POINT_DATA_SIZE + WKB_HEADER_SIZE))))
return GET_SIZE_ERROR;
return size;
} }
...@@ -1102,7 +1124,8 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const ...@@ -1102,7 +1124,8 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
return 1; return 1;
n_points= uint4korr(m_data); n_points= uint4korr(m_data);
if (no_data(m_data+4, if (n_points > max_n_points ||
no_data(m_data+4,
n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) || n_points * (SIZEOF_STORED_DOUBLE * 2 + WKB_HEADER_SIZE)) ||
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;
...@@ -1155,6 +1178,7 @@ const Geometry::Class_info *Gis_multi_point::get_class_info() const ...@@ -1155,6 +1178,7 @@ const Geometry::Class_info *Gis_multi_point::get_class_info() const
uint32 Gis_multi_line_string::get_data_size() const uint32 Gis_multi_line_string::get_data_size() const
{ {
uint32 n_line_strings; uint32 n_line_strings;
uint32 n_points;
const char *data= m_data; const char *data= m_data;
if (no_data(data, 4)) if (no_data(data, 4))
...@@ -1164,11 +1188,13 @@ uint32 Gis_multi_line_string::get_data_size() const ...@@ -1164,11 +1188,13 @@ uint32 Gis_multi_line_string::get_data_size() const
while (n_line_strings--) while (n_line_strings--)
{ {
if (no_data(data, WKB_HEADER_SIZE + 4)) if (no_data(data, WKB_HEADER_SIZE + 4) ||
(n_points= uint4korr(data + WKB_HEADER_SIZE)) > max_n_points)
return GET_SIZE_ERROR; return GET_SIZE_ERROR;
data+= (WKB_HEADER_SIZE + 4 + uint4korr(data + WKB_HEADER_SIZE) * data+= (WKB_HEADER_SIZE + 4 + n_points*POINT_DATA_SIZE);
POINT_DATA_SIZE);
} }
if (no_data(data, 0))
return GET_SIZE_ERROR;
return (uint32) (data - m_data); return (uint32) (data - m_data);
} }
...@@ -1260,7 +1286,8 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt, ...@@ -1260,7 +1286,8 @@ 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 (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)) txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1; return 1;
txt->qs_append('('); txt->qs_append('(');
...@@ -1321,7 +1348,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const ...@@ -1321,7 +1348,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
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 (n_points > max_n_points || no_data(data, length))
return 1; return 1;
if (!--num) if (!--num)
break; break;
...@@ -1401,6 +1428,7 @@ const Geometry::Class_info *Gis_multi_line_string::get_class_info() const ...@@ -1401,6 +1428,7 @@ const Geometry::Class_info *Gis_multi_line_string::get_class_info() const
uint32 Gis_multi_polygon::get_data_size() const uint32 Gis_multi_polygon::get_data_size() const
{ {
uint32 n_polygons; uint32 n_polygons;
uint32 n_points;
const char *data= m_data; const char *data= m_data;
if (no_data(data, 4)) if (no_data(data, 4))
...@@ -1419,11 +1447,14 @@ uint32 Gis_multi_polygon::get_data_size() const ...@@ -1419,11 +1447,14 @@ uint32 Gis_multi_polygon::get_data_size() const
while (n_linear_rings--) while (n_linear_rings--)
{ {
if (no_data(data, 4)) if (no_data(data, 4) ||
(n_points= uint4korr(data)) > max_n_points)
return GET_SIZE_ERROR; return GET_SIZE_ERROR;
data+= 4 + uint4korr(data) * POINT_DATA_SIZE; data+= 4 + n_points * POINT_DATA_SIZE;
} }
} }
if (no_data(data, 0))
return GET_SIZE_ERROR;
return (uint32) (data - m_data); return (uint32) (data - m_data);
} }
...@@ -1521,7 +1552,8 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const ...@@ -1521,7 +1552,8 @@ 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 (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, txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
512)) 512))
return 1; return 1;
...@@ -1604,6 +1636,8 @@ int Gis_multi_polygon::geometry_n(uint32 num, String *result) const ...@@ -1604,6 +1636,8 @@ int Gis_multi_polygon::geometry_n(uint32 num, String *result) const
if (no_data(data, 4)) if (no_data(data, 4))
return 1; return 1;
n_points= uint4korr(data); n_points= uint4korr(data);
if (n_points > max_n_points)
return 1;
data+= 4 + POINT_DATA_SIZE * n_points; data+= 4 + POINT_DATA_SIZE * n_points;
} }
} while (--num); } while (--num);
......
...@@ -196,6 +196,11 @@ struct Geometry_buffer; ...@@ -196,6 +196,11 @@ struct Geometry_buffer;
class Geometry class Geometry
{ {
public:
// Maximum number of points in feature that can fit into String
static const uint32 max_n_points=
(uint32) (INT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
POINT_DATA_SIZE;
public: public:
Geometry() {} /* Remove gcc warning */ Geometry() {} /* Remove gcc warning */
virtual ~Geometry() {} /* Remove gcc warning */ virtual ~Geometry() {} /* Remove gcc warning */
...@@ -379,10 +384,6 @@ public: ...@@ -379,10 +384,6 @@ public:
class Gis_line_string: public Geometry 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: public:
Gis_line_string() {} /* Remove gcc warning */ Gis_line_string() {} /* Remove gcc warning */
virtual ~Gis_line_string() {} /* Remove gcc warning */ virtual ~Gis_line_string() {} /* Remove gcc warning */
......
...@@ -9966,6 +9966,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -9966,6 +9966,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
} }
case Item::FIELD_ITEM: case Item::FIELD_ITEM:
case Item::DEFAULT_VALUE_ITEM: case Item::DEFAULT_VALUE_ITEM:
case Item::INSERT_VALUE_ITEM:
{ {
Item_field *field= (Item_field*) item; Item_field *field= (Item_field*) item;
bool orig_modify= modify_item; bool orig_modify= modify_item;
......
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