diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-26 03:49:45 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-26 03:49:45 +0000 |
commit | 1457ee2ce4582456a7226fe81b817abb9548813e (patch) | |
tree | e6b4321377bf89be71b98f7d7b6fa24ef1d9b16e /bignum.c | |
parent | 9be51267b54f923e9e95824984416eca9b95dd6c (diff) | |
download | ruby-1457ee2ce4582456a7226fe81b817abb9548813e.tar.gz |
* bignum.c (bigxor_int): Fix a buffer over read.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41640 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 27 |
1 files changed, 17 insertions, 10 deletions
@@ -4873,6 +4873,10 @@ bigxor_int(VALUE x, long y) sign = (y >= 0) ? 1 : 0; xds = BDIGITS(x); zn = xn = RBIGNUM_LEN(x); +#if SIZEOF_BDIGITS < SIZEOF_LONG + if (zn < bdigit_roomof(SIZEOF_LONG)) + zn = bdigit_roomof(SIZEOF_LONG); +#endif z = bignew(zn, !(RBIGNUM_SIGN(x) ^ sign)); zds = BDIGITS(z); @@ -4880,19 +4884,22 @@ bigxor_int(VALUE x, long y) i = 1; zds[0] = xds[0] ^ y; #else - { - long num = y; - - for (i=0; i<bdigit_roomof(SIZEOF_LONG); i++) { - zds[i] = xds[i] ^ BIGLO(num); - num = BIGDN(num); - } + for (i = 0; i < xn; i++) { + zds[i] = xds[i] ^ BIGLO(y); + y = BIGDN(y); + } + for (; i < zn; i++) { + zds[i] = (RBIGNUM_SIGN(x) ? 0 : BDIGMAX) ^ BIGLO(y); + y = BIGDN(y); } #endif - while (i < xn) { - zds[i] = sign?xds[i]:BIGLO(~xds[i]); - i++; + for (; i < xn; i++) { + zds[i] = sign ? xds[i] : BIGLO(~xds[i]); + } + for (; i < zn; i++) { + zds[i] = sign ^ RBIGNUM_SIGN(x) ? BDIGMAX : 0; } + if (!RBIGNUM_SIGN(z)) get2comp(z); return bignorm(z); } |