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