Commit d6d11c8e authored by Tor Didriksen's avatar Tor Didriksen

merge 5.1-security => 5.5-security

parents 55fd5189 5dc553cd
...@@ -1544,6 +1544,50 @@ select * from t1; ...@@ -1544,6 +1544,50 @@ select * from t1;
5.05 / 0.014 5.05 / 0.014
360.714286 360.714286
DROP TABLE t1; DROP TABLE t1;
#
# Bug#12563865
# ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
#
SELECT substring(('M') FROM (999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
foo
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: ''
Warning 1292 Truncated incorrect DECIMAL value: ''
SELECT min(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
foo
999999999999999999999999999999999999999999999999999999999999999999999999999999999
SELECT multipolygonfromtext(('4294967294.1'),(999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
foo
NULL
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: ''
SELECT convert((999999999999999999999999999999999999999999999999999999999999999999999999999999999), decimal(30,30)) AS foo;
foo
0.999999999999999999999999999999
Warnings:
Warning 1264 Out of range value for column 'foo' at row 1
SELECT bit_xor(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
foo
9223372036854775807
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: ''
SELECT -(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
foo
-999999999999999999999999999999999999999999999999999999999999999999999999999999999
SELECT date_sub((999999999999999999999999999999999999999999999999999999999999999999999999999999999),
interval ((SELECT date_add((0x77500000),
interval ('Oml') second)))
day_minute)
AS foo;
foo
NULL
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: ''
Warning 1292 Incorrect datetime value: '9223372036854775807'
SELECT truncate(999999999999999999999999999999999999999999999999999999999999999999999999999999999, 28) AS foo;
foo
999999999999999999999999999999999999999999999999999999999999999999999999999999999
End of 5.0 tests End of 5.0 tests
select cast(143.481 as decimal(4,1)); select cast(143.481 as decimal(4,1));
cast(143.481 as decimal(4,1)) cast(143.481 as decimal(4,1))
......
...@@ -1244,6 +1244,27 @@ show create table t1; ...@@ -1244,6 +1244,27 @@ show create table t1;
select * from t1; select * from t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#12563865
--echo # ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
--echo #
let $nine_81=
999999999999999999999999999999999999999999999999999999999999999999999999999999999;
eval SELECT substring(('M') FROM ($nine_81)) AS foo;
eval SELECT min($nine_81) AS foo;
eval SELECT multipolygonfromtext(('4294967294.1'),($nine_81)) AS foo;
eval SELECT convert(($nine_81), decimal(30,30)) AS foo;
eval SELECT bit_xor($nine_81) AS foo;
eval SELECT -($nine_81) AS foo;
eval SELECT date_sub(($nine_81),
interval ((SELECT date_add((0x77500000),
interval ('Oml') second)))
day_minute)
AS foo;
eval SELECT truncate($nine_81, 28) AS foo;
--echo End of 5.0 tests --echo End of 5.0 tests
# #
......
...@@ -98,12 +98,31 @@ inline int my_decimal_int_part(uint precision, uint decimals) ...@@ -98,12 +98,31 @@ inline int my_decimal_int_part(uint precision, uint decimals)
class my_decimal :public decimal_t class my_decimal :public decimal_t
{ {
/*
Several of the routines in strings/decimal.c have had buffer
overrun/underrun problems. These are *not* caught by valgrind.
To catch them, we allocate dummy fields around the buffer,
and test that their values do not change.
*/
#if !defined(DBUG_OFF)
int foo1;
#endif
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
#if !defined(DBUG_OFF)
int foo2;
static const int test_value= 123;
#endif
public: public:
my_decimal(const my_decimal &rhs) : decimal_t(rhs) my_decimal(const my_decimal &rhs) : decimal_t(rhs)
{ {
#if !defined(DBUG_OFF)
foo1= test_value;
foo2= test_value;
#endif
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++) for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
buffer[i]= rhs.buffer[i]; buffer[i]= rhs.buffer[i];
fix_buffer_pointer(); fix_buffer_pointer();
...@@ -111,6 +130,10 @@ public: ...@@ -111,6 +130,10 @@ public:
my_decimal& operator=(const my_decimal &rhs) my_decimal& operator=(const my_decimal &rhs)
{ {
#if !defined(DBUG_OFF)
foo1= test_value;
foo2= test_value;
#endif
if (this == &rhs) if (this == &rhs)
return *this; return *this;
decimal_t::operator=(rhs); decimal_t::operator=(rhs);
...@@ -122,6 +145,10 @@ public: ...@@ -122,6 +145,10 @@ public:
void init() void init()
{ {
#if !defined(DBUG_OFF)
foo1= test_value;
foo2= test_value;
#endif
len= DECIMAL_BUFF_LENGTH; len= DECIMAL_BUFF_LENGTH;
buf= buffer; buf= buffer;
} }
...@@ -130,6 +157,17 @@ public: ...@@ -130,6 +157,17 @@ public:
{ {
init(); init();
} }
~my_decimal()
{
sanity_check();
}
void sanity_check()
{
DBUG_ASSERT(foo1 == test_value);
DBUG_ASSERT(foo2 == test_value);
}
void fix_buffer_pointer() { buf= buffer; } void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal_t::sign; } bool sign() const { return decimal_t::sign; }
......
...@@ -1474,9 +1474,8 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1474,9 +1474,8 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
{ {
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1, int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit), frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len, intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
intg1=ROUND_UP(from->intg +
(((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0; dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
int first_dig; int first_dig;
...@@ -1491,6 +1490,12 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1491,6 +1490,12 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
default: DBUG_ASSERT(0); default: DBUG_ASSERT(0);
} }
/*
For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
For internal testing here (ifdef MAIN) we always use len == 100/4
*/
DBUG_ASSERT(from->len == to->len);
if (unlikely(frac0+intg0 > len)) if (unlikely(frac0+intg0 > len))
{ {
frac0=len-intg0; frac0=len-intg0;
...@@ -1504,17 +1509,17 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale, ...@@ -1504,17 +1509,17 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
return E_DEC_OK; return E_DEC_OK;
} }
if (to != from || intg1>intg0) if (to != from)
{ {
dec1 *p0= buf0+intg0+max(frac1, frac0); dec1 *p0= buf0+intg0+max(frac1, frac0);
dec1 *p1= buf1+intg1+max(frac1, frac0); dec1 *p1= buf1+intg0+max(frac1, frac0);
DBUG_ASSERT(p0 - buf0 <= len);
DBUG_ASSERT(p1 - buf1 <= len);
while (buf0 < p0) while (buf0 < p0)
*(--p1) = *(--p0); *(--p1) = *(--p0);
if (unlikely(intg1 > intg0))
to->buf[0]= 0;
intg0= intg1;
buf0=to->buf; buf0=to->buf;
buf1=to->buf; buf1=to->buf;
to->sign=from->sign; to->sign=from->sign;
......
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