Commit e8bc4e16 authored by unknown's avatar unknown

libmysql/libmysql.c:

 Fix for Bug#6025 "Test "client_test" fails in 4.1.6-gamma build (2)".
 No need for a test case, the bug is covered already.


libmysql/libmysql.c:
  Fix for Bug#6025 "Test "client_test" fails in 4.1.6-gamma build (2)":
  the bug was in assignments like:
    *row+= read_binary_time(tm, row);
  which makes two assingments without a sequence point (read_binary_*
  changes *row too) => undefined behaviour.
  The fix changes read_binary_{time,date,datetime} signature to get
  rid of any probability to fall into the same trouble in future.
parent feb23bf9
......@@ -3196,24 +3196,20 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
read_binary_{date,time,datetime}()
tm MYSQL_TIME structure to fill
pos pointer to current position in network buffer.
These functions increase pos to point to the beginning of this
field (this is just due to implementation of net_field_length
which is used to get length of binary representation of
time value).
These functions increase pos to point to the beginning of the
next column.
Auxiliary functions to read time (date, datetime) values from network
buffer and store in MYSQL_TIME structure. Jointly used by conversion
and no-conversion fetching.
*/
static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
static void read_binary_time(MYSQL_TIME *tm, uchar **pos)
{
uint length;
/* net_field_length will set pos to the first byte of data */
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
uint length= net_field_length(pos);
if (length)
{
uchar *to= *pos;
tm->neg= (bool) to[0];
......@@ -3226,17 +3222,18 @@ static uint read_binary_time(MYSQL_TIME *tm, uchar **pos)
tm->year= tm->month= 0;
tm->time_type= MYSQL_TIMESTAMP_TIME;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
{
uint length;
uint length= net_field_length(pos);
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
if (length)
{
uchar *to= *pos;
......@@ -3255,17 +3252,18 @@ static uint read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
tm->hour= tm->minute= tm->second= 0;
tm->second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
tm->time_type= MYSQL_TIMESTAMP_DATETIME;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
{
uint length;
uint length= net_field_length(pos);
if (!(length= net_field_length(pos)))
set_zero_time(tm);
else
if (length)
{
uchar *to= *pos;
tm->year = (uint) sint2korr(to);
......@@ -3276,8 +3274,11 @@ static uint read_binary_date(MYSQL_TIME *tm, uchar **pos)
tm->second_part= 0;
tm->neg= 0;
tm->time_type= MYSQL_TIMESTAMP_DATE;
*pos+= length;
}
return length;
else
set_zero_time(tm);
}
......@@ -3604,7 +3605,6 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
uchar **row)
{
ulong length;
enum enum_field_types field_type= field->type;
uint field_is_unsigned= field->flags & UNSIGNED_FLAG;
......@@ -3615,7 +3615,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong data= field_is_unsigned ? (longlong) (unsigned char) value :
(longlong) value;
fetch_long_with_conversion(param, field, data);
length= 1;
*row+= 1;
break;
}
case MYSQL_TYPE_SHORT:
......@@ -3625,7 +3625,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong data= field_is_unsigned ? (longlong) (unsigned short) value :
(longlong) value;
fetch_long_with_conversion(param, field, data);
length= 2;
*row+= 2;
break;
}
case MYSQL_TYPE_INT24: /* mediumint is sent as 4 bytes int */
......@@ -3635,14 +3635,14 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
longlong data= field_is_unsigned ? (longlong) (unsigned long) value :
(longlong) value;
fetch_long_with_conversion(param, field, data);
length= 4;
*row+= 4;
break;
}
case MYSQL_TYPE_LONGLONG:
{
longlong value= (longlong)sint8korr(*row);
fetch_long_with_conversion(param, field, value);
length= 8;
*row+= 8;
break;
}
case MYSQL_TYPE_FLOAT:
......@@ -3650,7 +3650,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
float value;
float4get(value,*row);
fetch_float_with_conversion(param, field, value, FLT_DIG);
length= 4;
*row+= 4;
break;
}
case MYSQL_TYPE_DOUBLE:
......@@ -3658,14 +3658,14 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
double value;
float8get(value,*row);
fetch_float_with_conversion(param, field, value, DBL_DIG);
length= 8;
*row+= 8;
break;
}
case MYSQL_TYPE_DATE:
{
MYSQL_TIME tm;
length= read_binary_date(&tm, row);
read_binary_date(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
......@@ -3673,7 +3673,7 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
{
MYSQL_TIME tm;
length= read_binary_time(&tm, row);
read_binary_time(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
......@@ -3682,16 +3682,18 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
{
MYSQL_TIME tm;
length= read_binary_datetime(&tm, row);
read_binary_datetime(&tm, row);
fetch_datetime_with_conversion(param, &tm);
break;
}
default:
length= net_field_length(row);
{
ulong length= net_field_length(row);
fetch_string_with_conversion(param, (char*) *row, length);
*row+= length;
break;
}
*row+= length;
}
}
......@@ -3760,19 +3762,19 @@ static void fetch_result_double(MYSQL_BIND *param, uchar **row)
static void fetch_result_time(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_time(tm, row);
read_binary_time(tm, row);
}
static void fetch_result_date(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_date(tm, row);
read_binary_date(tm, row);
}
static void fetch_result_datetime(MYSQL_BIND *param, uchar **row)
{
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
*row+= read_binary_datetime(tm, row);
read_binary_datetime(tm, row);
}
static void fetch_result_bin(MYSQL_BIND *param, uchar **row)
......
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