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

This commit is contained in:
malff/marcsql@weblab.(none) 2007-06-11 15:20:46 -06:00
parent 7b55e8b88e
commit 041c7797a9
2 changed files with 68 additions and 10 deletions

View File

@ -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,
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,
{ {
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)
(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)
(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,
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,
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,
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:
{ {

View File

@ -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[]= {
{ "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 }
}; };