Project

General

Profile

Actions

Bug #4248

closed

r30483 might cause underflow

Added by mame (Yusuke Endoh) almost 15 years ago. Updated over 14 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.3dev (2011-01-07 trunk 30456) [i686-linux]
Backport:
[ruby-core:34218]

Description

=begin
Hi, matz (or Ray Chason) --

http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30483

Author: matz
Date: Fri Jan 7 00:17:06 2011 UTC (9 hours, 45 minutes ago)
Log Message:

  • bignum.c (bigmul1_karatsuba): avoid overflow that make assertion
    fail in certain case. this patch is contributed from Ray Chason
    in personal communication.

I understand the possibility that zds may cause overflow, right?
Do you have the "certain case", or can you disclose the "personal
communication" ?
I suspect that this patch may cause t1's underflow instead of zds,
though it is difficult to create test case...
Anyway, the following patch is conservative, I think.

It may a good idea to consult ruby-core, especially, mrkn before
committing this kind of patch ;-)

I can realize this commit thanks to ruby-trunk-changes:

http://d.hatena.ne.jp/nagachika/20110107/ruby_trunk_changes_30480_30483

diff --git a/bignum.c b/bignum.c
index ede0de6..950222b 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2104,7 +2104,7 @@ bigmul1_karatsuba(VALUE x, VALUE y)
*/

  /* allocate a result bignum */
  • z = bignew(xn + yn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  • z = bignew(xn + yn + 1, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
    zds = BDIGITS(z);

    /* t1 <- xh * yh /
    @@ -2156,16 +2156,16 @@ bigmul1_karatsuba(VALUE x, VALUE y)
    /
    t3 <- xh * yh */
    t3 = bigmul0(xh, yh);

  • i = xn + yn - n;
  • /* subtract t1 from t3 */
  • bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t1), t1n, BDIGITS(t3), big_real_len(t3));
  • /* 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));
  • i = xn + yn - n + 1;
    /* 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 middle bytes of the result (z1) */

  • bigsub_core(zds + n, i, BDIGITS(t1), t1n, zds + n, i);

  • /* subtract t2 from middle bytes of the result (z1) */

  • if (t2 != Qundef) bigsub_core(zds + n, i, BDIGITS(t2), t2n, zds + n, i);

  • return z;
    }

--
Yusuke Endoh
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0