diff options
author | unknown <gshchepa/uchum@gleb.loc> | 2007-10-08 03:48:59 +0500 |
---|---|---|
committer | unknown <gshchepa/uchum@gleb.loc> | 2007-10-08 03:48:59 +0500 |
commit | 60761a7cc67a358861e4af7863b785adc449b92f (patch) | |
tree | 9ca852e262b3c8f4fa4b9cd92f183fa5aa598ce3 | |
parent | a408f34866de14649b13dc1e4c08edf40a19db28 (diff) | |
download | mariadb-git-60761a7cc67a358861e4af7863b785adc449b92f.tar.gz |
Fixed bug #31019: the MOD() function and the % operator crash the server
when a divisor is less than 1 and its fractional part is very long.
For example:
1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789;
Stack buffer overflow has been fixed in the do_div_mod function.
strings/decimal.c:
Fixed bug #31019.
Stack buffer overflow has been fixed in the do_div_mod function:
a value of the upper bound of the buffer was increased where
a decrement is required.
mysql-test/t/type_decimal.test:
Added test case for bug #31019.
mysql-test/r/type_decimal.result:
Added test case for bug #31019.
-rw-r--r-- | mysql-test/r/type_decimal.result | 6 | ||||
-rw-r--r-- | mysql-test/t/type_decimal.test | 8 | ||||
-rw-r--r-- | strings/decimal.c | 3 |
3 files changed, 16 insertions, 1 deletions
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 3cf24529421..72f827f11ed 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -799,3 +799,9 @@ SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; ROUND(qty,3) dps ROUND(qty,dps) 1.133 3 1.133 DROP TABLE t1; +SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%'; +% +0.012345687012345687012345687012345687012345687012345687012345687012345687000000000 +SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()'; +MOD() +0.012345687012345687012345687012345687012345687012345687012345687012345687000000000 diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 5538f19f5f9..c154b2685dd 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -408,3 +408,11 @@ INSERT INTO t1 VALUES (1.1325,3); SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; DROP TABLE t1; + +# +# Bug#31019: MOD() function and operator crashes MySQL when +# divisor is very long and < 1 +# + +SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%'; +SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()'; diff --git a/strings/decimal.c b/strings/decimal.c index f1f02f3a071..cbea0e340c6 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -2323,11 +2323,12 @@ static int do_div_mod(decimal_t *from1, decimal_t *from2, } if (unlikely(intg0+frac0 > to->len)) { - stop1-=to->len-frac0-intg0; + stop1-=frac0+intg0-to->len; frac0=to->len-intg0; to->frac=frac0*DIG_PER_DEC1; error=E_DEC_TRUNCATED; } + DBUG_ASSERT(buf0 + (stop1 - start1) <= to->buf + to->len); while (start1 < stop1) *buf0++=*start1++; } |