* bignum.c (bigadd_int): Fix a buffer over read.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41636 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2013-06-25 21:53:58 +00:00
Родитель 46979cdb96
Коммит 5026d0ae75
2 изменённых файлов: 50 добавлений и 16 удалений

Просмотреть файл

@ -1,3 +1,7 @@
Wed Jun 26 06:48:07 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (bigadd_int): Fix a buffer over read.
Wed Jun 26 01:18:13 2013 Masaya Tarui <tarui@ruby-lang.org> Wed Jun 26 01:18:13 2013 Masaya Tarui <tarui@ruby-lang.org>
* gc.c (is_before_sweep): Add new helper function that check the object * gc.c (is_before_sweep): Add new helper function that check the object

Просмотреть файл

@ -3195,12 +3195,16 @@ bigadd_int(VALUE x, long y)
xds = BDIGITS(x); xds = BDIGITS(x);
xn = RBIGNUM_LEN(x); xn = RBIGNUM_LEN(x);
if (xn < 2) { if (xn == 0)
zn = 3; return LONG2NUM(y);
}
else { zn = xn;
zn = xn + 1; #if SIZEOF_BDIGITS < SIZEOF_LONG
} if (zn < bdigit_roomof(SIZEOF_LONG))
zn = bdigit_roomof(SIZEOF_LONG);
#endif
zn++;
z = bignew(zn, RBIGNUM_SIGN(x)); z = bignew(zn, RBIGNUM_SIGN(x));
zds = BDIGITS(z); zds = BDIGITS(z);
@ -3209,29 +3213,55 @@ bigadd_int(VALUE x, long y)
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 y_is_zero_z;
#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)xds[i] + BIGLO(y); num += (BDIGIT_DBL)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) {
num += xds[i]; for (;i < xn; i++) {
zds[i++] = BIGLO(num); y_is_zero_x:
if (num == 0) goto num_is_zero_x;
num += (BDIGIT_DBL)xds[i];
zds[i] = BIGLO(num);
num = BIGDN(num); num = BIGDN(num);
} }
if (num) zds[i++] = (BDIGIT)num; for (; i < zn; i++) {
else while (i < xn) { y_is_zero_z:
if (num == 0) goto num_is_zero_z;
zds[i] = BIGLO(num);
num = BIGDN(num);
}
goto finish;
for (;i < xn; i++) {
num_is_zero_x:
zds[i] = xds[i]; zds[i] = xds[i];
i++;
} }
assert(i <= zn); for (; i < zn; i++) {
while (i < zn) { num_is_zero_z:
zds[i++] = 0; zds[i] = 0;
} }
goto finish;
finish:
RB_GC_GUARD(x); RB_GC_GUARD(x);
return bignorm(z); return bignorm(z);
} }