Commit 5ddc564d authored by dlenev@mysql.com's avatar dlenev@mysql.com

Proposed fix for bug #6439 "from_unixtime() function returns wrong datetime

values for too big argument".

Added range checking for from_unixtime() argument, cleaned up code 
a bit.
parent 476cd83b
...@@ -470,3 +470,9 @@ unix_timestamp(@a) ...@@ -470,3 +470,9 @@ unix_timestamp(@a)
select unix_timestamp('1969-12-01 19:00:01'); select unix_timestamp('1969-12-01 19:00:01');
unix_timestamp('1969-12-01 19:00:01') unix_timestamp('1969-12-01 19:00:01')
0 0
select from_unixtime(0);
from_unixtime(0)
NULL
select from_unixtime(2145916800);
from_unixtime(2145916800)
NULL
...@@ -225,3 +225,10 @@ drop table t1,t2,t3; ...@@ -225,3 +225,10 @@ drop table t1,t2,t3;
select @a:=FROM_UNIXTIME(1); select @a:=FROM_UNIXTIME(1);
select unix_timestamp(@a); select unix_timestamp(@a);
select unix_timestamp('1969-12-01 19:00:01'); select unix_timestamp('1969-12-01 19:00:01');
#
# Test for bug #6439 "unix_timestamp() function returns wrong datetime
# values for too big argument". It should return error instead.
#
select from_unixtime(0);
select from_unixtime(2145916800);
...@@ -919,21 +919,14 @@ String *Item_func_date_format::val_str(String *str) ...@@ -919,21 +919,14 @@ String *Item_func_date_format::val_str(String *str)
String *Item_func_from_unixtime::val_str(String *str) String *Item_func_from_unixtime::val_str(String *str)
{ {
struct tm tm_tmp,*start; TIME ltime;
time_t tmp=(time_t) args[0]->val_int(); if (get_date(&ltime, 0))
if ((null_value=args[0]->null_value))
return 0; return 0;
localtime_r(&tmp,&tm_tmp);
start=&tm_tmp;
if (str->alloc(20)) if (str->alloc(20))
return str; /* purecov: inspected */ return str; /* purecov: inspected */
sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d", sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d",
(int) start->tm_year+1900, (int) ltime.year, (int) ltime.month, (int) ltime.day,
(int) start->tm_mon+1, (int) ltime.hour, (int) ltime.minute, (int) ltime.second);
(int) start->tm_mday,
(int) start->tm_hour,
(int) start->tm_min,
(int) start->tm_sec);
str->length(19); str->length(19);
return str; return str;
} }
...@@ -941,37 +934,33 @@ String *Item_func_from_unixtime::val_str(String *str) ...@@ -941,37 +934,33 @@ String *Item_func_from_unixtime::val_str(String *str)
longlong Item_func_from_unixtime::val_int() longlong Item_func_from_unixtime::val_int()
{ {
time_t tmp=(time_t) (ulong) args[0]->val_int(); TIME ltime;
if ((null_value=args[0]->null_value)) if (get_date(&ltime, 0))
return 0; return 0;
struct tm tm_tmp,*start; return ((longlong)(ltime.year*10000L+ltime.month*100+ltime.day)*LL(1000000)+
localtime_r(&tmp,&tm_tmp); (longlong)(ltime.hour*10000L+ltime.minute*100+ltime.second));
start= &tm_tmp;
return ((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
(((uint) start->tm_mon+1)*100+
(uint) start->tm_mday))*LL(1000000)+
(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+
(uint) start->tm_sec)));
} }
bool Item_func_from_unixtime::get_date(TIME *ltime, bool Item_func_from_unixtime::get_date(TIME *ltime,
bool fuzzy_date __attribute__((unused))) bool fuzzy_date __attribute__((unused)))
{ {
time_t tmp=(time_t) (ulong) args[0]->val_int(); struct tm tm_tmp;
if ((null_value=args[0]->null_value)) time_t tmp;
longlong arg= args[0]->val_int();
if ((null_value= (args[0]->null_value ||
arg < TIMESTAMP_MIN_VALUE ||
arg > TIMESTAMP_MAX_VALUE)))
return 1; return 1;
struct tm tm_tmp,*start; tmp= arg;
localtime_r(&tmp,&tm_tmp); localtime_r(&tmp,&tm_tmp);
start= &tm_tmp; ltime->year= tm_tmp.tm_year+1900;
ltime->year= start->tm_year+1900; ltime->month= tm_tmp.tm_mon+1;
ltime->month= start->tm_mon+1; ltime->day= tm_tmp.tm_mday;
ltime->day= start->tm_mday; ltime->hour= tm_tmp.tm_hour;
ltime->hour= start->tm_hour; ltime->minute= tm_tmp.tm_min;
ltime->minute=start->tm_min; ltime->second= tm_tmp.tm_sec;
ltime->second=start->tm_sec; ltime->second_part= 0;
ltime->second_part=0; ltime->neg= 0;
ltime->neg=0;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment