Manual merge of Bug 27592 (5.0-runtime to 5.1-runtime)

parent 7b55e8b8
...@@ -4397,7 +4397,7 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg, ...@@ -4397,7 +4397,7 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
const char *field_name_arg, const char *field_name_arg,
TABLE_SHARE *share, TABLE_SHARE *share,
CHARSET_INFO *cs) 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, cs) unireg_check_arg, field_name_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4414,7 +4414,8 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg, ...@@ -4414,7 +4414,8 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
Field_timestamp::Field_timestamp(bool maybe_null_arg, Field_timestamp::Field_timestamp(bool maybe_null_arg,
const char *field_name_arg, const char *field_name_arg,
CHARSET_INFO *cs) CHARSET_INFO *cs)
:Field_str((uchar*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0, :Field_str((uchar*) 0, MAX_DATETIME_WIDTH,
maybe_null_arg ? (uchar*) "": 0, 0,
NONE, field_name_arg, cs) NONE, field_name_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4947,7 +4948,7 @@ String *Field_time::val_str(String *val_buffer, ...@@ -4947,7 +4948,7 @@ String *Field_time::val_str(String *val_buffer,
{ {
ASSERT_COLUMN_MARKED_FOR_READ; ASSERT_COLUMN_MARKED_FOR_READ;
MYSQL_TIME ltime; MYSQL_TIME ltime;
val_buffer->alloc(19); val_buffer->alloc(MAX_DATE_STRING_REP_LENGTH);
long tmp=(long) sint3korr(ptr); long tmp=(long) sint3korr(ptr);
ltime.neg= 0; ltime.neg= 0;
if (tmp < 0) if (tmp < 0)
...@@ -5495,7 +5496,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type) ...@@ -5495,7 +5496,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error)) MODE_INVALID_DATES))), &error))
{ {
char buff[12]; char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1); String str(buff, sizeof(buff), &my_charset_latin1);
make_date((DATE_TIME_FORMAT *) 0, ltime, &str); make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
...@@ -5726,7 +5727,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) ...@@ -5726,7 +5727,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type)
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
MODE_INVALID_DATES))), &error)) MODE_INVALID_DATES))), &error))
{ {
char buff[19]; char buff[MAX_DATE_STRING_REP_LENGTH];
String str(buff, sizeof(buff), &my_charset_latin1); String str(buff, sizeof(buff), &my_charset_latin1);
make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
...@@ -5802,7 +5803,7 @@ String *Field_datetime::val_str(String *val_buffer, ...@@ -5802,7 +5803,7 @@ String *Field_datetime::val_str(String *val_buffer,
part1=(long) (tmp/LL(1000000)); part1=(long) (tmp/LL(1000000));
part2=(long) (tmp - (ulonglong) part1*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--=0;
*pos--= (char) ('0'+(char) (part2%10)); part2/=10; *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
*pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
...@@ -8911,15 +8912,18 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8911,15 +8912,18 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
break; break;
case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_TIMESTAMP:
if (!fld_length) 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 We support only even TIMESTAMP lengths less or equal than 14
and 19 as length of 4.1 compatible representation. and 19 as length of 4.1 compatible representation.
*/ */
length= ((length+1)/2)*2; /* purecov: inspected */ 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; flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
if (fld_default_value) if (fld_default_value)
...@@ -8972,7 +8976,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8972,7 +8976,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
length= 10; length= 10;
break; break;
case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME:
length= 19; length= MAX_DATETIME_WIDTH;
break; break;
case MYSQL_TYPE_SET: case MYSQL_TYPE_SET:
{ {
......
...@@ -16161,6 +16161,59 @@ static void test_bug27876() ...@@ -16161,6 +16161,59 @@ static void test_bug27876()
} }
/*
Bug#27592 (stack overrun when storing datetime value using prepared statements)
*/
static void test_bug27592()
{
const int NUM_ITERATIONS= 40;
int i;
int rc;
MYSQL_STMT *stmt= NULL;
MYSQL_BIND bind[1];
MYSQL_TIME time_val;
DBUG_ENTER("test_bug27592");
myheader("test_bug27592");
mysql_query(mysql, "DROP TABLE IF EXISTS t1");
mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
DIE_UNLESS(stmt);
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_DATETIME;
bind[0].buffer= (char *) &time_val;
bind[0].length= NULL;
for (i= 0; i < NUM_ITERATIONS; i++)
{
time_val.year= 2007;
time_val.month= 6;
time_val.day= 7;
time_val.hour= 18;
time_val.minute= 41;
time_val.second= 3;
time_val.second_part=0;
time_val.neg=0;
rc= mysql_stmt_bind_param(stmt, bind);
check_execute(stmt, rc);
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
}
mysql_stmt_close(stmt);
DBUG_VOID_RETURN;
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -16449,6 +16502,7 @@ static struct my_tests_st my_tests[]= { ...@@ -16449,6 +16502,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug28075", test_bug28075 }, { "test_bug28075", test_bug28075 },
#endif #endif
{ "test_bug27876", test_bug27876 }, { "test_bug27876", test_bug27876 },
{ "test_bug27592", test_bug27592 },
{ 0, 0 } { 0, 0 }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment