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