зеркало из https://github.com/github/ruby.git
bignum.c (estimate_initial_sqrt): prevent integer overflow
`Integer.sqrt(0xffff_ffff_ffff_ffff ** 2)` caused assertion failure because of integer overflow. [ruby-core:95453] [Bug #16269]
This commit is contained in:
Родитель
c8f97d1620
Коммит
f364564e66
10
bignum.c
10
bignum.c
|
@ -6888,7 +6888,15 @@ estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len)
|
|||
rshift /= 2;
|
||||
rshift += (2-(len&1))*BITSPERDIG/2;
|
||||
if (rshift >= 0) {
|
||||
d <<= rshift;
|
||||
if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) {
|
||||
/* (d << rshift) does cause overflow.
|
||||
* example: Integer.sqrt(0xffff_ffff_ffff_ffff ** 2)
|
||||
*/
|
||||
d = ~(BDIGIT_DBL)0;
|
||||
}
|
||||
else {
|
||||
d <<= rshift;
|
||||
}
|
||||
}
|
||||
BDIGITS_ZERO(xds, xn-2);
|
||||
bdigitdbl2bary(&xds[xn-2], 2, d);
|
||||
|
|
|
@ -640,6 +640,9 @@ class TestInteger < Test::Unit::TestCase
|
|||
failures << n unless root*root <= n && (root+1)*(root+1) > n
|
||||
end
|
||||
assert_empty(failures, bug13440)
|
||||
|
||||
x = 0xffff_ffff_ffff_ffff
|
||||
assert_equal(x, Integer.sqrt(x ** 2), "[ruby-core:95453]")
|
||||
end
|
||||
|
||||
def test_fdiv
|
||||
|
|
Загрузка…
Ссылка в новой задаче