summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <dlenev@mysql.com>2004-11-15 16:11:13 +0300
committerunknown <dlenev@mysql.com>2004-11-15 16:11:13 +0300
commitc4134b7a82cfc5532e840ab1e91ae063357daf56 (patch)
tree883ce23f2f0f06f70d75e1d70b11971967eea535
parentb3e00b67500638b5e8ae4715c8f8c18a8b51ba65 (diff)
downloadmariadb-git-c4134b7a82cfc5532e840ab1e91ae063357daf56.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.result6
-rw-r--r--mysql-test/t/func_time.test7
-rw-r--r--sql/item_timefunc.cc57
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(&ltime, 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(&ltime, 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;
}