1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#12563865 ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0

Buffer over-run on all platforms, crash on windows, wrong result on other platforms,
when rounding numbers which start with 999999999 and have
precision = 9 or 18 or 27 or 36 ...


mysql-test/r/type_newdecimal.result:
  New test cases.
mysql-test/t/type_newdecimal.test:
  New test cases.
sql/my_decimal.h:
  Add sanity checking code, to catch buffer over/under-run.
strings/decimal.c:
  The original initialization of intg1 (add 1 if buf[0] == DIG_MAX)
  will set p1 to point outside the buffer, and the loop to copy the original value
      while (buf0 < p0)
        *(--p1) = *(--p0);
  will overwrite memory outside the my_decimal object.
This commit is contained in:
Tor Didriksen
2011-10-14 10:09:53 +02:00
parent 98231daa6f
commit a6145f4b62
4 changed files with 108 additions and 8 deletions

View File

@ -86,12 +86,31 @@ inline int my_decimal_int_part(uint precision, uint decimals)
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];
#if !defined(DBUG_OFF)
int foo2;
static const int test_value= 123;
#endif
public:
void init()
{
#if !defined(DBUG_OFF)
foo1= test_value;
foo2= test_value;
#endif
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
#if !defined (HAVE_purify) && !defined(DBUG_OFF)
@ -104,6 +123,17 @@ public:
{
init();
}
~my_decimal()
{
sanity_check();
}
void sanity_check()
{
DBUG_ASSERT(foo1 == test_value);
DBUG_ASSERT(foo2 == test_value);
}
void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal_t::sign; }