List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:April 27 2011 7:36am
Subject:bzr commit into mysql-5.1 branch (sergey.glukhov:3673) Bug#11889186
View as plain text  
#At file:///home/gluh/MySQL/mysql-5.1/ based on revid:guilhem.bichot@stripped

 3673 Sergey Glukhov	2011-04-27
      Bug#11889186  60503: CRASH IN MAKE_DATE_TIME WITH DATE_FORMAT / STR_TO_DATE COMBINATION
      calc_daynr() function returns negative result
      if malformed date with zero year and month is used.
      Attempt to calculate week day on negative value
      leads to crash. The fix is return NULL for
      'W', 'a', 'w' specifiers if zero year and month is used.
      Additional fix for calc_daynr():
      --added assertion that result can not be negative
      --return 0 if zero year and month is used
     @ mysql-test/r/func_time.result
        test case
     @ mysql-test/t/func_time.test
        test case
     @ sql-common/my_time.c
        --added assertion that result can not be negative
        --return 0 if zero year and month is used
     @ sql/item_timefunc.cc
        eturn NULL for 'W', 'a', 'w' specifiers
        if zero year and month is used.

    modified:
      mysql-test/r/func_time.result
      mysql-test/t/func_time.test
      sql-common/my_time.c
      sql/item_timefunc.cc
=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result	2011-03-30 07:08:35 +0000
+++ b/mysql-test/r/func_time.result	2011-04-27 07:35:57 +0000
@@ -1405,4 +1405,16 @@ NULL
 SELECT ADDDATE(MONTH(FROM_UNIXTIME(NULL)),INTERVAL 1 HOUR);
 ADDDATE(MONTH(FROM_UNIXTIME(NULL)),INTERVAL 1 HOUR)
 NULL
+#
+# Bug#11889186  60503: CRASH IN MAKE_DATE_TIME WITH DATE_FORMAT / STR_TO_DATE COMBINATION
+#
+SELECT DATE_FORMAT('0000-00-11', '%W');
+DATE_FORMAT('0000-00-11', '%W')
+NULL
+SELECT DATE_FORMAT('0000-00-11', '%a');
+DATE_FORMAT('0000-00-11', '%a')
+NULL
+SELECT DATE_FORMAT('0000-00-11', '%w');
+DATE_FORMAT('0000-00-11', '%w')
+NULL
 End of 5.1 tests

=== modified file 'mysql-test/t/func_time.test'
--- a/mysql-test/t/func_time.test	2011-03-30 07:08:35 +0000
+++ b/mysql-test/t/func_time.test	2011-04-27 07:35:57 +0000
@@ -913,4 +913,12 @@ SELECT CAST((MONTH(FROM_UNIXTIME(@@GLOBA
 
 SELECT ADDDATE(MONTH(FROM_UNIXTIME(NULL)),INTERVAL 1 HOUR);
 
+--echo #
+--echo # Bug#11889186  60503: CRASH IN MAKE_DATE_TIME WITH DATE_FORMAT / STR_TO_DATE COMBINATION
+--echo #
+
+SELECT DATE_FORMAT('0000-00-11', '%W');
+SELECT DATE_FORMAT('0000-00-11', '%a');
+SELECT DATE_FORMAT('0000-00-11', '%w');
+
 --echo End of 5.1 tests

=== modified file 'sql-common/my_time.c'
--- a/sql-common/my_time.c	2011-02-02 17:05:28 +0000
+++ b/sql-common/my_time.c	2011-04-27 07:35:57 +0000
@@ -772,7 +772,7 @@ long calc_daynr(uint year,uint month,uin
   int y= year;                                  /* may be < 0 temporarily */
   DBUG_ENTER("calc_daynr");
 
-  if (y == 0 && month == 0 && day == 0)
+  if (y == 0 && month == 0)
     DBUG_RETURN(0);				/* Skip errors */
   /* Cast to int to be able to handle month == 0 */
   delsum= (long) (365 * y + 31 *((int) month - 1) + (int) day);
@@ -783,6 +783,7 @@ long calc_daynr(uint year,uint month,uin
   temp=(int) ((y/100+1)*3)/4;
   DBUG_PRINT("exit",("year: %d  month: %d  day: %d -> daynr: %ld",
 		     y+(month <= 2),month,day,delsum+y/4-temp));
+  DBUG_ASSERT(delsum+(int) y/4-temp > 0);
   DBUG_RETURN(delsum+(int) y/4-temp);
 } /* calc_daynr */
 

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2011-03-28 13:24:25 +0000
+++ b/sql/item_timefunc.cc	2011-04-27 07:35:57 +0000
@@ -648,7 +648,7 @@ bool make_date_time(DATE_TIME_FORMAT *fo
                     system_charset_info);
         break;
       case 'W':
-        if (type == MYSQL_TIMESTAMP_TIME)
+        if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
           return 1;
         weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
                               l_time->day),0);
@@ -657,7 +657,7 @@ bool make_date_time(DATE_TIME_FORMAT *fo
                     system_charset_info);
         break;
       case 'a':
-        if (type == MYSQL_TIMESTAMP_TIME)
+        if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
           return 1;
         weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
                              l_time->day),0);
@@ -816,7 +816,7 @@ bool make_date_time(DATE_TIME_FORMAT *fo
       }
       break;
       case 'w':
-	if (type == MYSQL_TIMESTAMP_TIME)
+	if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
 	  return 1;
 	weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
 					l_time->day),1);


Attachment: [text/bzr-bundle] bzr/sergey.glukhov@oracle.com-20110427073557-b7028gag212n8e0y.bundle
Thread
bzr commit into mysql-5.1 branch (sergey.glukhov:3673) Bug#11889186Sergey Glukhov27 Apr