ruby-changes:29584
From: akr <ko1@a...>
Date: Wed, 26 Jun 2013 06:54:12 +0900 (JST)
Subject: [ruby-changes:29584] akr:r41636 (trunk): * bignum.c (bigadd_int): Fix a buffer over read.
akr 2013-06-26 06:53:58 +0900 (Wed, 26 Jun 2013) New Revision: 41636 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41636 Log: * bignum.c (bigadd_int): Fix a buffer over read. Modified files: trunk/ChangeLog trunk/bignum.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41635) +++ ChangeLog (revision 41636) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jun 26 06:48:07 2013 Tanaka Akira <akr@f...> + + * bignum.c (bigadd_int): Fix a buffer over read. + Wed Jun 26 01:18:13 2013 Masaya Tarui <tarui@r...> * gc.c (is_before_sweep): Add new helper function that check the object Index: bignum.c =================================================================== --- bignum.c (revision 41635) +++ bignum.c (revision 41636) @@ -3195,12 +3195,16 @@ bigadd_int(VALUE x, long y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L3195 xds = BDIGITS(x); xn = RBIGNUM_LEN(x); - if (xn < 2) { - zn = 3; - } - else { - zn = xn + 1; - } + if (xn == 0) + return LONG2NUM(y); + + zn = xn; +#if SIZEOF_BDIGITS < SIZEOF_LONG + if (zn < bdigit_roomof(SIZEOF_LONG)) + zn = bdigit_roomof(SIZEOF_LONG); +#endif + zn++; + z = bignew(zn, RBIGNUM_SIGN(x)); zds = BDIGITS(z); @@ -3209,29 +3213,55 @@ bigadd_int(VALUE x, long y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L3213 zds[0] = BIGLO(num); num = BIGDN(num); i = 1; + if (i < xn) + goto y_is_zero_x; + goto y_is_zero_z; #else num = 0; - for (i=0; i<bdigit_roomof(SIZEOF_LONG); i++) { + for (i=0; i < xn; i++) { + if (y == 0) goto y_is_zero_x; num += (BDIGIT_DBL)xds[i] + BIGLO(y); zds[i] = BIGLO(num); num = BIGDN(num); y = BIGDN(y); } + for (; i < zn; i++) { + if (y == 0) goto y_is_zero_z; + num += BIGLO(y); + zds[i] = BIGLO(num); + num = BIGDN(num); + y = BIGDN(y); + } + goto finish; + #endif - while (num && i < xn) { - num += xds[i]; - zds[i++] = BIGLO(num); + + for (;i < xn; i++) { + y_is_zero_x: + if (num == 0) goto num_is_zero_x; + num += (BDIGIT_DBL)xds[i]; + zds[i] = BIGLO(num); + num = BIGDN(num); + } + for (; i < zn; i++) { + y_is_zero_z: + if (num == 0) goto num_is_zero_z; + zds[i] = BIGLO(num); num = BIGDN(num); } - if (num) zds[i++] = (BDIGIT)num; - else while (i < xn) { + goto finish; + + for (;i < xn; i++) { + num_is_zero_x: zds[i] = xds[i]; - i++; } - assert(i <= zn); - while (i < zn) { - zds[i++] = 0; + for (; i < zn; i++) { + num_is_zero_z: + zds[i] = 0; } + goto finish; + + finish: RB_GC_GUARD(x); return bignorm(z); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/