* bignum.c (bigsub_int): Fix a buffer over read.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
56435700df
commit
4d906fbc14
@ -1,3 +1,7 @@
|
|||||||
|
Wed Jun 26 01:17:29 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (bigsub_int): Fix a buffer over read.
|
||||||
|
|
||||||
Tue Jun 25 22:45:43 2013 Tanaka Akira <akr@fsij.org>
|
Tue Jun 25 22:45:43 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* bignum.c (rb_absint_singlebit_p): Use POW2_P.
|
* bignum.c (rb_absint_singlebit_p): Use POW2_P.
|
||||||
|
63
bignum.c
63
bignum.c
@ -3091,7 +3091,7 @@ bigsub_int(VALUE x, long y0)
|
|||||||
{
|
{
|
||||||
VALUE z;
|
VALUE z;
|
||||||
BDIGIT *xds, *zds;
|
BDIGIT *xds, *zds;
|
||||||
long xn;
|
long xn, zn;
|
||||||
BDIGIT_DBL_SIGNED num;
|
BDIGIT_DBL_SIGNED num;
|
||||||
long i, y;
|
long i, y;
|
||||||
|
|
||||||
@ -3099,10 +3099,19 @@ bigsub_int(VALUE x, long y0)
|
|||||||
xds = BDIGITS(x);
|
xds = BDIGITS(x);
|
||||||
xn = RBIGNUM_LEN(x);
|
xn = RBIGNUM_LEN(x);
|
||||||
|
|
||||||
z = bignew(xn, RBIGNUM_SIGN(x));
|
if (xn == 0)
|
||||||
|
return LONG2NUM(-y0);
|
||||||
|
|
||||||
|
zn = xn;
|
||||||
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
|
if (zn < bdigit_roomof(SIZEOF_LONG))
|
||||||
|
zn = bdigit_roomof(SIZEOF_LONG);
|
||||||
|
#endif
|
||||||
|
z = bignew(zn, RBIGNUM_SIGN(x));
|
||||||
zds = BDIGITS(z);
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
||||||
|
assert(xn == zn);
|
||||||
num = (BDIGIT_DBL_SIGNED)xds[0] - y;
|
num = (BDIGIT_DBL_SIGNED)xds[0] - y;
|
||||||
if (xn == 1 && num < 0) {
|
if (xn == 1 && num < 0) {
|
||||||
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
|
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
|
||||||
@ -3113,26 +3122,62 @@ bigsub_int(VALUE x, long y0)
|
|||||||
zds[0] = BIGLO(num);
|
zds[0] = BIGLO(num);
|
||||||
num = BIGDN(num);
|
num = BIGDN(num);
|
||||||
i = 1;
|
i = 1;
|
||||||
|
if (i < xn)
|
||||||
|
goto y_is_zero_x;
|
||||||
|
goto finish;
|
||||||
#else
|
#else
|
||||||
num = 0;
|
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_SIGNED)xds[i] - BIGLO(y);
|
num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
|
||||||
zds[i] = BIGLO(num);
|
zds[i] = BIGLO(num);
|
||||||
num = BIGDN(num);
|
num = BIGDN(num);
|
||||||
y = BIGDN(y);
|
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
|
#endif
|
||||||
while (num && i < xn) {
|
|
||||||
|
for (; i < xn; i++) {
|
||||||
|
y_is_zero_x:
|
||||||
|
if (num == 0) goto num_is_zero_x;
|
||||||
num += xds[i];
|
num += xds[i];
|
||||||
zds[i++] = BIGLO(num);
|
zds[i] = BIGLO(num);
|
||||||
num = BIGDN(num);
|
num = BIGDN(num);
|
||||||
}
|
}
|
||||||
while (i < xn) {
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
zds[i] = xds[i];
|
for (; i < zn; i++) {
|
||||||
i++;
|
y_is_zero_z:
|
||||||
|
if (num == 0) goto num_is_zero_z;
|
||||||
|
zds[i] = BIGLO(num);
|
||||||
|
num = BIGDN(num);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
for (; i < xn; i++) {
|
||||||
|
num_is_zero_x:
|
||||||
|
zds[i] = xds[i];
|
||||||
|
}
|
||||||
|
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||||
|
for (; i < zn; i++) {
|
||||||
|
num_is_zero_z:
|
||||||
|
zds[i] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
assert(num == 0 || num == -1);
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
z = bigsub(x, rb_int2big(y0));
|
get2comp(z);
|
||||||
|
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
|
||||||
}
|
}
|
||||||
RB_GC_GUARD(x);
|
RB_GC_GUARD(x);
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user