Commit a0f300a6 authored by Tatjana Azundris Nuernberg's avatar Tatjana Azundris Nuernberg

auto-merge Bug#11762799/Bug#55436

parents 37f49e69 2683078d
......@@ -1920,4 +1920,17 @@ SELECT SUM(DISTINCT a) FROM t1;
SUM(DISTINCT a)
0.0000
DROP TABLE t1;
#
# Bug#55436: buffer overflow in debug binary of dbug_buff in
# Field_new_decimal::store_value
#
SET SQL_MODE='';
CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM;
INSERT INTO t1 SET f1 = -64878E-85;
Warnings:
Note 1265 Data truncated for column 'f1' at row 1
SELECT f1 FROM t1;
f1
0.000000000000000000000000
DROP TABLE IF EXISTS t1;
End of 5.1 tests
......@@ -1519,4 +1519,19 @@ SELECT AVG(DISTINCT a) FROM t1;
SELECT SUM(DISTINCT a) FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug#55436: buffer overflow in debug binary of dbug_buff in
--echo # Field_new_decimal::store_value
--echo #
# this threw memory warnings on Windows. Also make sure future changes
# don't change these results, as per usual.
SET SQL_MODE='';
CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM;
INSERT INTO t1 SET f1 = -64878E-85;
SELECT f1 FROM t1;
DROP TABLE IF EXISTS t1;
--echo End of 5.1 tests
......@@ -2608,7 +2608,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
DBUG_ENTER("Field_new_decimal::store_value");
#ifndef DBUG_OFF
{
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
char dbug_buff[DECIMAL_MAX_STR_LENGTH+2];
DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, decimal_value)));
}
#endif
......@@ -2623,7 +2623,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
}
#ifndef DBUG_OFF
{
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
char dbug_buff[DECIMAL_MAX_STR_LENGTH+2];
DBUG_PRINT("info", ("saving with precision %d scale: %d value %s",
(int)precision, (int)dec,
dbug_decimal_as_string(dbug_buff, decimal_value)));
......@@ -2692,7 +2692,7 @@ int Field_new_decimal::store(const char *from, uint length,
}
#ifndef DBUG_OFF
char dbug_buff[DECIMAL_MAX_STR_LENGTH+1];
char dbug_buff[DECIMAL_MAX_STR_LENGTH+2];
DBUG_PRINT("enter", ("value: %s",
dbug_decimal_as_string(dbug_buff, &decimal_value)));
#endif
......
......@@ -99,10 +99,11 @@ int my_decimal2string(uint mask, const my_decimal *d,
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
the user requested, plus one for a possible decimal point, plus
one if the user only wanted decimal places, but we force a leading
zero on them. Because the type is implicitly UNSIGNED, we do not
need to reserve a character for the sign. For all other cases,
fixed_prec will be 0, and my_decimal_string_length() will be called
instead to calculate the required size of the buffer.
zero on them, plus one for the '\0' terminator. Because the type
is implicitly UNSIGNED, we do not need to reserve a character for
the sign. For all other cases, fixed_prec will be 0, and
my_decimal_string_length() will be called instead to calculate the
required size of the buffer.
*/
int length= (fixed_prec
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
......@@ -332,7 +333,7 @@ print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length)
const char *dbug_decimal_as_string(char *buff, const my_decimal *val)
{
int length= DECIMAL_MAX_STR_LENGTH;
int length= DECIMAL_MAX_STR_LENGTH + 1; /* minimum size for buff */
if (!val)
return "NULL";
(void)decimal2string((decimal_t*) val, buff, &length, 0,0,0);
......
......@@ -62,7 +62,7 @@ typedef struct st_mysql_time MYSQL_TIME;
/**
maximum length of string representation (number of maximum decimal
digits + 1 position for sign + 1 position for decimal point)
digits + 1 position for sign + 1 position for decimal point, no terminator)
*/
#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
......@@ -243,6 +243,7 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
inline
int my_decimal_string_length(const my_decimal *d)
{
/* length of string representation including terminating '\0' */
return decimal_string_size(d);
}
......
......@@ -312,8 +312,8 @@ int decimal_actual_fraction(decimal_t *from)
from - value to convert
to - points to buffer where string representation
should be stored
*to_len - in: size of to buffer
out: length of the actually written string
*to_len - in: size of to buffer (incl. terminating '\0')
out: length of the actually written string (excl. '\0')
fixed_precision - 0 if representation can be variable length and
fixed_decimals will not be checked in this case.
Put number as with fixed point position with this
......@@ -330,6 +330,7 @@ int decimal2string(decimal_t *from, char *to, int *to_len,
int fixed_precision, int fixed_decimals,
char filler)
{
/* {intg_len, frac_len} output widths; {intg, frac} places in input */
int len, intg, frac= from->frac, i, intg_len, frac_len, fill;
/* number digits before decimal point */
int fixed_intg= (fixed_precision ?
......
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