diff options
author | kaa@polly.local <> | 2006-10-04 17:13:32 +0400 |
---|---|---|
committer | kaa@polly.local <> | 2006-10-04 17:13:32 +0400 |
commit | 609a3cd2953458626065e1f0b288c1dc5bd3e877 (patch) | |
tree | 8b8e52453890c27a4b5e0e288b80cc0ccc883b0a /sql/field.cc | |
parent | 66fa757e1f6a3d9373119ac5437e490ead191411 (diff) | |
download | mariadb-git-609a3cd2953458626065e1f0b288c1dc5bd3e877.tar.gz |
Fixes a number of problems with time/datetime <-> string conversion functions:
- bug #11655 "Wrong time is returning from nested selects - maximum time exists
- input and output TIME values were not validated properly in several conversion functions
- bug #20927 "sec_to_time treats big unsigned as signed"
- integer overflows were not checked in several functions. As a result, input values like 2^32 or 3600*2^32 were treated as 0
- BIGINT UNSIGNED values were treated as SIGNED in several functions
- in cases where both input string truncation and out-of-range TIME value occur, only 'truncated incorrect time value' warning was produced
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/sql/field.cc b/sql/field.cc index 3cb0c0d3a7c..484758fb0e7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3961,9 +3961,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; - int error; + int error= 0; + int warning; - if (str_to_time(from, len, <ime, &error)) + if (str_to_time(from, len, <ime, &warning)) { tmp=0L; error= 2; @@ -3972,29 +3973,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } else { - if (error) + if (warning & MYSQL_TIME_WARN_TRUNCATED) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_TIME, 1); - - if (ltime.month) - ltime.day=0; - tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); - if (tmp > 8385959) + if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE) { - tmp=8385959; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_TIME, !error); error= 1; } + if (ltime.month) + ltime.day=0; + tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); if (error > 1) error= 2; } if (ltime.neg) tmp= -tmp; - error |= Field_time::store((longlong) tmp); + int3store(ptr,tmp); return error; } @@ -4003,16 +4002,16 @@ int Field_time::store(double nr) { long tmp; int error= 0; - if (nr > 8385959.0) + if (nr > (double)TIME_MAX_VALUE) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } - else if (nr < -8385959.0) + else if (nr < (double)-TIME_MAX_VALUE) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; @@ -4040,17 +4039,17 @@ int Field_time::store(longlong nr) { long tmp; int error= 0; - if (nr > (longlong) 8385959L) + if (nr > (longlong) TIME_MAX_VALUE) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr < (longlong) -8385959L) + else if (nr < (longlong) -TIME_MAX_VALUE) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); |