Commit 5afdd974 authored by unknown's avatar unknown

Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-base

into  weblab.(none):/home/marcsql/TREE/mysql-5.0-rt-merge


sql/field.cc:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
parents d37e1642 0e958122
...@@ -4254,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, ...@@ -4254,7 +4254,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
const char *field_name_arg, const char *field_name_arg,
struct st_table *table_arg, struct st_table *table_arg,
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, table_arg, cs) unireg_check_arg, field_name_arg, table_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4272,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, ...@@ -4272,7 +4272,8 @@ Field_timestamp::Field_timestamp(char *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,
struct st_table *table_arg, CHARSET_INFO *cs) 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) NONE, field_name_arg, table_arg, cs)
{ {
/* For 4.0 MYD and 4.0 InnoDB compatibility */ /* For 4.0 MYD and 4.0 InnoDB compatibility */
...@@ -4803,7 +4804,7 @@ String *Field_time::val_str(String *val_buffer, ...@@ -4803,7 +4804,7 @@ String *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
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)
...@@ -5339,7 +5340,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) ...@@ -5339,7 +5340,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,
...@@ -5564,7 +5565,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) ...@@ -5564,7 +5565,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,
...@@ -5638,7 +5639,7 @@ String *Field_datetime::val_str(String *val_buffer, ...@@ -5638,7 +5639,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);
...@@ -8536,15 +8537,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8536,15 +8537,18 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
break; break;
case FIELD_TYPE_TIMESTAMP: case FIELD_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)
...@@ -8597,7 +8601,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8597,7 +8601,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
length= 10; length= 10;
break; break;
case FIELD_TYPE_DATETIME: case FIELD_TYPE_DATETIME:
length= 19; length= MAX_DATETIME_WIDTH;
break; break;
case FIELD_TYPE_SET: case FIELD_TYPE_SET:
{ {
......
...@@ -51,7 +51,7 @@ static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime, ...@@ -51,7 +51,7 @@ static bool make_datetime(date_time_format_types format, MYSQL_TIME *ltime,
{ {
char *buff; char *buff;
CHARSET_INFO *cs= &my_charset_bin; CHARSET_INFO *cs= &my_charset_bin;
uint length= 30; uint length= MAX_DATE_STRING_REP_LENGTH;
if (str->alloc(length)) if (str->alloc(length))
return 1; return 1;
...@@ -1400,7 +1400,7 @@ String *Item_date::val_str(String *str) ...@@ -1400,7 +1400,7 @@ String *Item_date::val_str(String *str)
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE)) if (get_date(&ltime, TIME_FUZZY_DATE))
return (String *) 0; return (String *) 0;
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String *) 0; return (String *) 0;
...@@ -1449,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec() ...@@ -1449,7 +1449,7 @@ void Item_func_curdate::fix_length_and_dec()
String *Item_func_curdate::val_str(String *str) String *Item_func_curdate::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String *) 0; return (String *) 0;
...@@ -1678,7 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str) ...@@ -1678,7 +1678,8 @@ String *Item_func_sec_to_time::val_str(String *str)
MYSQL_TIME ltime; MYSQL_TIME ltime;
longlong arg_val= args[0]->val_int(); longlong arg_val= args[0]->val_int();
if ((null_value=args[0]->null_value) || str->alloc(19)) if ((null_value=args[0]->null_value) ||
str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return (String*) 0; return (String*) 0;
...@@ -1863,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str) ...@@ -1863,6 +1864,10 @@ String *Item_func_date_format::val_str(String *str)
size=max_length; size=max_length;
else else
size=format_length(format); size=format_length(format);
if (size < MAX_DATE_STRING_REP_LENGTH)
size= MAX_DATE_STRING_REP_LENGTH;
if (format == str) if (format == str)
str= &value; // Save result here str= &value; // Save result here
if (str->alloc(size)) if (str->alloc(size))
...@@ -1906,13 +1911,14 @@ String *Item_func_from_unixtime::val_str(String *str) ...@@ -1906,13 +1911,14 @@ String *Item_func_from_unixtime::val_str(String *str)
if (get_date(&time_tmp, 0)) if (get_date(&time_tmp, 0))
return 0; return 0;
if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
} }
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str); make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
return str; return str;
} }
...@@ -1975,13 +1981,14 @@ String *Item_func_convert_tz::val_str(String *str) ...@@ -1975,13 +1981,14 @@ String *Item_func_convert_tz::val_str(String *str)
if (get_date(&time_tmp, 0)) if (get_date(&time_tmp, 0))
return 0; return 0;
if (str->alloc(20*MY_CHARSET_BIN_MB_MAXLEN)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
} }
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str); make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
return str; return str;
} }
...@@ -2561,6 +2568,7 @@ String *Item_datetime_typecast::val_str(String *str) ...@@ -2561,6 +2568,7 @@ String *Item_datetime_typecast::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) && if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME, !make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
&ltime, str)) &ltime, str))
...@@ -2639,7 +2647,8 @@ String *Item_date_typecast::val_str(String *str) ...@@ -2639,7 +2647,8 @@ String *Item_date_typecast::val_str(String *str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) && !str->alloc(11)) if (!get_arg0_date(&ltime, TIME_FUZZY_DATE) &&
!str->alloc(MAX_DATE_STRING_REP_LENGTH))
{ {
make_date((DATE_TIME_FORMAT *) 0, &ltime, str); make_date((DATE_TIME_FORMAT *) 0, &ltime, str);
return str; return str;
...@@ -2692,7 +2701,7 @@ String *Item_func_makedate::val_str(String *str) ...@@ -2692,7 +2701,7 @@ String *Item_func_makedate::val_str(String *str)
{ {
null_value=0; null_value=0;
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day); get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
if (str->alloc(11)) if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
goto err; goto err;
make_date((DATE_TIME_FORMAT *) 0, &l_time, str); make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
return str; return str;
...@@ -2828,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str) ...@@ -2828,6 +2837,7 @@ String *Item_func_add_time::val_str(String *str)
days= (long)(seconds/86400L); days= (long)(seconds/86400L);
calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds); calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);
if (!is_time) if (!is_time)
{ {
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
...@@ -2943,7 +2953,7 @@ String *Item_func_maketime::val_str(String *str) ...@@ -2943,7 +2953,7 @@ String *Item_func_maketime::val_str(String *str)
args[2]->null_value || args[2]->null_value ||
minute < 0 || minute > 59 || minute < 0 || minute > 59 ||
second < 0 || second > 59 || second < 0 || second > 59 ||
str->alloc(19)))) str->alloc(MAX_DATE_STRING_REP_LENGTH))))
return 0; return 0;
bzero((char *)&ltime, sizeof(ltime)); bzero((char *)&ltime, sizeof(ltime));
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */ #define MAX_TIME_WIDTH 23 /* -DDDDDD HH:MM:SS.###### */
#define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */ #define MAX_DATETIME_FULL_WIDTH 29 /* YYYY-MM-DD HH:MM:SS.###### AM */
#define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */ #define MAX_DATETIME_WIDTH 19 /* YYYY-MM-DD HH:MM:SS */
#define MAX_DATETIME_COMPRESSED_WIDTH 14 /* YYYYMMDDHHMMSS */
#define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */ #define MAX_TABLES (sizeof(table_map)*8-3) /* Max tables in join */
#define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3)) #define PARAM_TABLE_BIT (((table_map) 1) << (sizeof(table_map)*8-3))
......
...@@ -15623,6 +15623,59 @@ static void test_bug27876() ...@@ -15623,6 +15623,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
*/ */
...@@ -15904,6 +15957,7 @@ static struct my_tests_st my_tests[]= { ...@@ -15904,6 +15957,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug21635", test_bug21635 }, { "test_bug21635", test_bug21635 },
{ "test_bug24179", test_bug24179 }, { "test_bug24179", test_bug24179 },
{ "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