Hi

I run mysql3.23.49/myisam with linux 2.4.18/libc2.2.5.
Some time ago I've hardware crash. Myisamchk didn't report
any problems but after some time mysql got SIGSEGV.
>From that time mysql finished with SIGSEGV in the same place
a few times.
0x80cb554 handle_segfault__Fi + 428
0x40021f54 _end + 935829740
0x4014e1a3 _end + 937059131
0x80c8e2a append__6StringPCcUi + 206
0x80b3cb4 val_str__21Item_func_date_formatP6String + 1652

The problem is with
item_timefunc.cc: String *Item_func_date_format::val_str(String *str)
when there is corupted data in database.
Only way to get rid of corupted data was mysqldump and import myisamchk
will not help.

In case of corupted date
field.cc: bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
returns strange values in ltime, for example
l_time.month=4321234 or l_time.hour=43
and therefore
in Item_func_date_format::val_str(String *str)
 str->append(month_names[l_time.month-1].ptr(),3);
goes with invalid pointer and causes SEGV

Below there's my patch but probably there is better way to avoid the
problem.

--- item_timefunc.cc.old        Wed Jun 12 19:15:31 2002
+++ item_timefunc.cc    Wed Jun 12 20:02:26 2002
@@ -680,6 +680,12 @@
   }
   str->length(0);

+/* Lets check if l_time is valid in case our data is corupted
+it may be done in field.cc:bool Field_datetime::get_date(TIME *ltime,bool fuzzydate)
+but... */
+/* I check only month,weekday -> too big values
+will cause SIGSEGV with day/month_names[], hours and minutes aren't dangerous */
+
   /* Create the result string */
   const char *ptr=format->ptr();
   const char *end=ptr+format->length();
@@ -691,7 +697,7 @@
     {
       switch (*++ptr) {
       case 'M':
-       if(!l_time.month)
+       if(l_time.month<1 || l_time.month>12)
        {
          null_value=1;
          return 0;
@@ -699,7 +705,7 @@
        str->append(month_names[l_time.month-1]);
        break;
       case 'b':
-       if(!l_time.month)
+       if(l_time.month<1 || l_time.month>12)
        {
          null_value=1;
          return 0;
@@ -713,6 +719,10 @@
          return 0;
        }

weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0);
+       if(weekday<0 || weekday>6) {
+         null_value=1;
+         return 0;
+       }
        str->append(day_names[weekday]);
        break;
       case 'a':
@@ -722,6 +732,10 @@
          return 0;
        }
        weekday=calc_weekday(calc_daynr(l_time.year,l_time.month,l_time.day),0);
+       if(weekday<0 || weekday>6) {
+         null_value=1;
+         return 0;
+       }
        str->append(day_names[weekday].ptr(),3);
        break;
       case 'D':



---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to