diff options
author | unknown <dlenev@mysql.com> | 2004-11-15 16:11:13 +0300 |
---|---|---|
committer | unknown <dlenev@mysql.com> | 2004-11-15 16:11:13 +0300 |
commit | e1509cf78105e95f7e335f33bd3349ea77a099ac (patch) | |
tree | 883ce23f2f0f06f70d75e1d70b11971967eea535 | |
parent | b80ed3bbb4a37a5be99e26aad6ab27b4ae34aa80 (diff) | |
download | mariadb-git-e1509cf78105e95f7e335f33bd3349ea77a099ac.tar.gz |
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.
mysql-test/r/func_time.result:
Test for bug #6439 "from_unixtime() function returns wrong datetime
values for too big argument".
mysql-test/t/func_time.test:
Test for bug #6439 "from_unixtime() function returns wrong datetime
values for too big argument".
sql/item_timefunc.cc:
Item_func_from_unixtime:
Added error range checking for function argument + small code clean up.
-rw-r--r-- | mysql-test/r/func_time.result | 6 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 7 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 57 |
3 files changed, 36 insertions, 34 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 877ca0e2d51..32034bf289d 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -470,3 +470,9 @@ unix_timestamp(@a) select unix_timestamp('1969-12-01 19:00:01'); unix_timestamp('1969-12-01 19:00:01') 0 +select from_unixtime(0); +from_unixtime(0) +NULL +select from_unixtime(2145916800); +from_unixtime(2145916800) +NULL diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index fffda12c14e..da18269cf6a 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -225,3 +225,10 @@ drop table t1,t2,t3; select @a:=FROM_UNIXTIME(1); select unix_timestamp(@a); 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); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ed950a33166..d188310be24 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -919,21 +919,14 @@ String *Item_func_date_format::val_str(String *str) String *Item_func_from_unixtime::val_str(String *str) { - struct tm tm_tmp,*start; - time_t tmp=(time_t) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + TIME ltime; + if (get_date(<ime, 0)) return 0; - localtime_r(&tmp,&tm_tmp); - start=&tm_tmp; if (str->alloc(20)) return str; /* purecov: inspected */ sprintf((char*) str->ptr(),"%04d-%02d-%02d %02d:%02d:%02d", - (int) start->tm_year+1900, - (int) start->tm_mon+1, - (int) start->tm_mday, - (int) start->tm_hour, - (int) start->tm_min, - (int) start->tm_sec); + (int) ltime.year, (int) ltime.month, (int) ltime.day, + (int) ltime.hour, (int) ltime.minute, (int) ltime.second); str->length(19); return str; } @@ -941,37 +934,33 @@ String *Item_func_from_unixtime::val_str(String *str) longlong Item_func_from_unixtime::val_int() { - time_t tmp=(time_t) (ulong) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + TIME ltime; + if (get_date(<ime, 0)) return 0; - struct tm tm_tmp,*start; - localtime_r(&tmp,&tm_tmp); - 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))); + return ((longlong)(ltime.year*10000L+ltime.month*100+ltime.day)*LL(1000000)+ + (longlong)(ltime.hour*10000L+ltime.minute*100+ltime.second)); } bool Item_func_from_unixtime::get_date(TIME *ltime, bool fuzzy_date __attribute__((unused))) { - time_t tmp=(time_t) (ulong) args[0]->val_int(); - if ((null_value=args[0]->null_value)) + struct tm tm_tmp; + 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; - struct tm tm_tmp,*start; + tmp= arg; localtime_r(&tmp,&tm_tmp); - start= &tm_tmp; - ltime->year= start->tm_year+1900; - ltime->month= start->tm_mon+1; - ltime->day= start->tm_mday; - ltime->hour= start->tm_hour; - ltime->minute=start->tm_min; - ltime->second=start->tm_sec; - ltime->second_part=0; - ltime->neg=0; + ltime->year= tm_tmp.tm_year+1900; + ltime->month= tm_tmp.tm_mon+1; + ltime->day= tm_tmp.tm_mday; + ltime->hour= tm_tmp.tm_hour; + ltime->minute= tm_tmp.tm_min; + ltime->second= tm_tmp.tm_sec; + ltime->second_part= 0; + ltime->neg= 0; return 0; } |