List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:December 21 2010 11:34am
Subject:bzr commit into mysql-5.1-bugteam branch (sergey.glukhov:3531) Bug#58030
View as plain text  
#At file:///home/gluh/MySQL/mysql-5.1-bugteam/ based on revid:dao-gang.qu@stripped

 3531 Sergey Glukhov	2010-12-21
      Bug#58030 crash in Item_func_geometry_from_text::val_str
      Item_sum_max/Item_sum_min incorrectly set null_value flag and
      attempt to get result in parent functions leads to crash.
      This happens due to double evaluation of the function argumet.
      First evaluation happens in the comparator and second one
      happens in Item_cache::cache_value().
      The fix is to introduce new Item_cache object which
      holds result of the argument and use this cached value
      as an argument of the comparator.
     @ mysql-test/r/func_group.result
        test case
     @ mysql-test/t/func_group.test
        test case
     @ sql/item.cc
        added assertion that ether we have some result or result is NULL.
     @ sql/item_sum.cc
        introduce new Item_cache object which
        holds result of the argument and use this cached value
        as an argument of the comparator.
     @ sql/item_sum.h
        introduce new Item_cache object which
        holds result of the argument and use this cached value
        as an argument of the comparator.

    modified:
      mysql-test/r/func_group.result
      mysql-test/t/func_group.test
      sql/item.cc
      sql/item_sum.cc
      sql/item_sum.h
=== modified file 'mysql-test/r/func_group.result'
--- a/mysql-test/r/func_group.result	2010-08-27 09:44:35 +0000
+++ b/mysql-test/r/func_group.result	2010-12-21 11:34:11 +0000
@@ -1724,4 +1724,16 @@ m
 1
 DROP TABLE t1;
 #
+#  Bug#58030 crash in Item_func_geometry_from_text::val_str
+#
+SELECT MAX(TIMESTAMP(RAND(0)));
+SELECT MIN(TIMESTAMP(RAND(0)));
+#
+#  Bug#58177 crash and valgrind warnings in decimal and protocol sending functions...
+#
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+#
 End of 5.1 tests

=== modified file 'mysql-test/t/func_group.test'
--- a/mysql-test/t/func_group.test	2010-08-27 09:44:35 +0000
+++ b/mysql-test/t/func_group.test	2010-12-21 11:34:11 +0000
@@ -1097,5 +1097,25 @@ SELECT MAX((SELECT 1 FROM t1 ORDER BY @v
 DROP TABLE t1;
 
 --echo #
+--echo #  Bug#58030 crash in Item_func_geometry_from_text::val_str
+--echo #
+
+--disable_result_log
+
+SELECT MAX(TIMESTAMP(RAND(0)));
+SELECT MIN(TIMESTAMP(RAND(0)));
+
+--echo #
+--echo #  Bug#58177 crash and valgrind warnings in decimal and protocol sending functions...
+--echo #
+
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+SELECT MIN(GET_LOCK('aaaaaaaaaaaaaaaaa',0) / '0b1111111111111111111111111111111111111111111111111111111111111111111111111' ^ (RAND()));
+
+--enable_result_log
+
+--echo #
 --echo End of 5.1 tests
 

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2010-12-14 09:33:03 +0000
+++ b/sql/item.cc	2010-12-21 11:34:11 +0000
@@ -5572,6 +5572,10 @@ bool Item::send(Protocol *protocol, Stri
     String *res;
     if ((res=val_str(buffer)))
       result= protocol->store(res->ptr(),res->length(),res->charset());
+    else
+    {
+      DBUG_ASSERT(null_value);
+    }
     break;
   }
   case MYSQL_TYPE_TINY:

=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc	2010-12-14 20:57:41 +0000
+++ b/sql/item_sum.cc	2010-12-21 11:34:11 +0000
@@ -666,8 +666,10 @@ void Item_sum_hybrid::setup_hybrid(Item 
   value= Item_cache::get_cache(item);
   value->setup(item);
   value->store(value_arg);
+  arg_cache= Item_cache::get_cache(item);
+  arg_cache->setup(item);
   cmp= new Arg_comparator();
-  cmp->set_cmp_func(this, args, (Item**)&value, FALSE);
+  cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE);
   collation.set(item->collation);
 }
 
@@ -1639,11 +1641,11 @@ Item *Item_sum_min::copy_or_same(THD* th
 bool Item_sum_min::add()
 {
   /* args[0] < value */
-  int res= cmp->compare();
-  if (!args[0]->null_value &&
-      (null_value || res < 0))
+  arg_cache->cache_value();
+  if (!arg_cache->null_value &&
+      (null_value || cmp->compare() < 0))
   {
-    value->store(args[0]);
+    value->store(arg_cache);
     value->cache_value();
     null_value= 0;
   }
@@ -1662,11 +1664,11 @@ Item *Item_sum_max::copy_or_same(THD* th
 bool Item_sum_max::add()
 {
   /* args[0] > value */
-  int res= cmp->compare();
-  if (!args[0]->null_value &&
-      (null_value || res > 0))
+  arg_cache->cache_value();
+  if (!arg_cache->null_value &&
+      (null_value || cmp->compare() > 0))
   {
-    value->store(args[0]);
+    value->store(arg_cache);
     value->cache_value();
     null_value= 0;
   }

=== modified file 'sql/item_sum.h'
--- a/sql/item_sum.h	2010-08-27 09:44:35 +0000
+++ b/sql/item_sum.h	2010-12-21 11:34:11 +0000
@@ -823,7 +823,7 @@ class Item_cache;
 class Item_sum_hybrid :public Item_sum
 {
 protected:
-  Item_cache *value;
+  Item_cache *value, *arg_cache;
   Arg_comparator *cmp;
   Item_result hybrid_type;
   enum_field_types hybrid_field_type;
@@ -832,14 +832,14 @@ protected:
 
   public:
   Item_sum_hybrid(Item *item_par,int sign)
-    :Item_sum(item_par), value(0), cmp(0),
+    :Item_sum(item_par), value(0), arg_cache(0), cmp(0),
     hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG),
     cmp_sign(sign), was_values(TRUE)
   { collation.set(&my_charset_bin); }
   Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
-    :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
-    hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
-    was_values(item->was_values)
+    :Item_sum(thd, item), value(item->value), arg_cache(0),
+    hybrid_type(item->hybrid_type), hybrid_field_type(item->hybrid_field_type),
+    cmp_sign(item->cmp_sign), was_values(item->was_values)
   { }
   bool fix_fields(THD *, Item **);
   void setup_hybrid(Item *item, Item *value_arg);


Attachment: [text/bzr-bundle] bzr/sergey.glukhov@oracle.com-20101221113411-aggnvlrbao9o1e3o.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (sergey.glukhov:3531) Bug#58030Sergey Glukhov21 Dec