diff options
author | unknown <anozdrin/alik@ibm.> | 2007-06-07 13:50:22 +0400 |
---|---|---|
committer | unknown <anozdrin/alik@ibm.> | 2007-06-07 13:50:22 +0400 |
commit | 727757d299c2476488543c5758f50ae6e15d4211 (patch) | |
tree | 42589384c4f4a48c1770c087d523b020f2ce80bb /sql/field.cc | |
parent | e21076463c4c1721bfd7150ff2350d634009755a (diff) | |
download | mariadb-git-727757d299c2476488543c5758f50ae6e15d4211.tar.gz |
Fix for BUG#27592: stack overrun when storing datetime value
using prepared statements.
sql/field.cc:
Using MAX_DATETIME_WIDTH or MAX_DATETIME_COMPRESSED_WIDTH
constants for the length of DATETIME fields.
Using MAX_DATE_STRING_REP_LENGTH for allocating buffers
for date/time/... string representation.
sql/item_timefunc.cc:
Using MAX_DATETIME_WIDTH or MAX_DATETIME_COMPRESSED_WIDTH
constants for the length of DATETIME fields.
Using MAX_DATE_STRING_REP_LENGTH for allocating buffers
for date/time/... string representation.
sql/unireg.h:
Introduce a constant for length of datetime compressed
format (YYYYMMDDHHMMSS).
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/sql/field.cc b/sql/field.cc index 8186659ae89..d69324141ce 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4285,7 +4285,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, const char *field_name_arg, struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, + :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg, cs) { /* For 4.0 MYD and 4.0 InnoDB compatibility */ @@ -4303,7 +4303,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, Field_timestamp::Field_timestamp(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str((char*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0, + :Field_str((char*) 0, MAX_DATETIME_WIDTH, + maybe_null_arg ? (uchar*) "": 0, 0, NONE, field_name_arg, table_arg, cs) { /* For 4.0 MYD and 4.0 InnoDB compatibility */ @@ -4834,7 +4835,7 @@ String *Field_time::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { MYSQL_TIME ltime; - val_buffer->alloc(19); + val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH); long tmp=(long) sint3korr(ptr); ltime.neg= 0; if (tmp < 0) @@ -5370,7 +5371,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error)) { - char buff[12]; + char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); make_date((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, @@ -5595,7 +5596,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error)) { - char buff[19]; + char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, @@ -5669,7 +5670,7 @@ String *Field_datetime::val_str(String *val_buffer, part1=(long) (tmp/LL(1000000)); part2=(long) (tmp - (ulonglong) part1*LL(1000000)); - pos=(char*) val_buffer->ptr()+19; + pos= (char*) val_buffer->ptr() + MAX_DATETIME_WIDTH; *pos--=0; *pos--= (char) ('0'+(char) (part2%10)); part2/=10; *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); @@ -8565,15 +8566,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, break; case FIELD_TYPE_TIMESTAMP: if (!fld_length) - length= 14; /* Full date YYYYMMDDHHMMSS */ - else if (length != 19) + { + /* Compressed date YYYYMMDDHHMMSS */ + length= MAX_DATETIME_COMPRESSED_WIDTH; + } + else if (length != MAX_DATETIME_WIDTH) { /* We support only even TIMESTAMP lengths less or equal than 14 and 19 as length of 4.1 compatible representation. */ length= ((length+1)/2)*2; /* purecov: inspected */ - length= min(length,14); /* purecov: inspected */ + length= min(length, MAX_DATETIME_COMPRESSED_WIDTH); /* purecov: inspected */ } flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; if (fld_default_value) @@ -8626,7 +8630,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, length= 10; break; case FIELD_TYPE_DATETIME: - length= 19; + length= MAX_DATETIME_WIDTH; break; case FIELD_TYPE_SET: { |