summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--bignum.c12
2 files changed, 12 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 4ea901ce2d..644d67dd97 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,12 @@ Fri Jan 7 00:37:35 2011 Tanaka Akira <akr@fsij.org>
* string.c: parenthesize macro arguments.
+Thu Jan 6 22:42:02 2011 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * bignum.c (bigmul1_karatsuba): avoid overflow that make assertion
+ fail in certain case. this patch is contributed from Ray Chason
+ <chasonr at gmail.com> in personal communication.
+
Thu Jan 6 20:55:49 2011 NAKAMURA Usaku <usa@ruby-lang.org>
* lib/mkmf.rb (create_makefile): ignore rest from first dot from
diff --git a/bignum.c b/bignum.c
index 2f804db5df..ede0de6523 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2157,14 +2157,14 @@ bigmul1_karatsuba(VALUE x, VALUE y)
t3 = bigmul0(xh, yh);
i = xn + yn - n;
- /* add t3 to middle bytes of the result (z1) */
- bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
+ /* subtract t1 from t3 */
+ bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t1), t1n, BDIGITS(t3), big_real_len(t3));
- /* subtract t1 from middle bytes of the result (z1) */
- bigsub_core(zds + n, i, BDIGITS(t1), t1n, zds + n, i);
+ /* subtract t2 from t3; t3 is now the middle term of the product */
+ if (t2 != Qundef) bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t2), t2n, BDIGITS(t3), big_real_len(t3));
- /* subtract t2 from middle bytes of the result (z1) */
- if (t2 != Qundef) bigsub_core(zds + n, i, BDIGITS(t2), t2n, zds + n, i);
+ /* add t3 to middle bytes of the result (z1) */
+ bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
return z;
}