summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-10-08 03:48:59 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-10-08 03:48:59 +0500
commit60761a7cc67a358861e4af7863b785adc449b92f (patch)
tree9ca852e262b3c8f4fa4b9cd92f183fa5aa598ce3
parenta408f34866de14649b13dc1e4c08edf40a19db28 (diff)
downloadmariadb-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.result6
-rw-r--r--mysql-test/t/type_decimal.test8
-rw-r--r--strings/decimal.c3
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++;
}