summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-03-09 11:59:47 +0100
committerSergei Golubchik <sergii@pisem.net>2011-03-09 11:59:47 +0100
commit3c6ff364ca31c9b8bc14f5fe583cd60ee5516bfd (patch)
tree9eacec19253684370625e03db243663f2b38d30d /sql/item_timefunc.cc
parenteeb7f5129b7e404b1612f1a39c243f3678c89117 (diff)
downloadmariadb-git-3c6ff364ca31c9b8bc14f5fe583cd60ee5516bfd.tar.gz
lp:731815 Crash/valgrind warning Item::send with 5.1-micro
Two problems: * Item_func_convert_tz() did not tell args[0] that it needs TIME_NO_ZERO_IN_DATE result * Item_func_timediff did not respect fuzzy_date limitations, truncated seconds when casting to signed long, resulting in invalid time value (hours, seconds = (uint)-1).
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r--sql/item_timefunc.cc10
1 files changed, 9 insertions, 1 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 813f4d61f2f..1575c1345af 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1872,7 +1872,8 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
to_tz_cached= args[2]->const_item();
}
- if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, TIME_NO_ZERO_DATE))
+ if (from_tz==0 || to_tz==0 ||
+ get_arg0_date(ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
{
null_value= 1;
return 1;
@@ -2534,6 +2535,9 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
l_time1.time_type != l_time2.time_type)
goto null_date;
+ if (fuzzy_date & TIME_NO_ZERO_IN_DATE)
+ goto null_date;
+
if (l_time1.neg != l_time2.neg)
l_sign= -l_sign;
@@ -2550,8 +2554,12 @@ bool Item_func_timediff::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
if (l_time1.neg && (seconds || microseconds))
l_time3.neg= 1-l_time3.neg; // Swap sign of result
+ set_if_smaller(seconds, INT_MAX32);
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
+ if ((fuzzy_date & TIME_NO_ZERO_DATE) && (seconds == 0) && (microseconds == 0))
+ goto null_date;
+
*ltime= l_time3;
check_time_range(ltime, &was_cut);