summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--bignum.c10
-rw-r--r--test/-ext-/num2int/test_num2int.rb15
3 files changed, 17 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a229ff735..5c5939531e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Nov 13 10:23:48 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * bignum.c (rb_big2ull): fix off-by-twice bug of NUM2ULL.
+ * test/-ext-/num2int/test_num2int.rb (class TestNum2int):
+ fix a testcase too.
+
Sun Nov 13 10:22:44 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* test/-ext-/num2int/test_num2int.rb (class TestNum2int):
diff --git a/bignum.c b/bignum.c
index 7bcc4c7935..91c275e605 100644
--- a/bignum.c
+++ b/bignum.c
@@ -1257,8 +1257,14 @@ rb_big2ull(VALUE x)
{
unsigned LONG_LONG num = big2ull(x, "unsigned long long");
- if (!RBIGNUM_SIGN(x))
- return (VALUE)(-(SIGNED_VALUE)num);
+ if (!RBIGNUM_SIGN(x)) {
+ VALUE v = (VALUE)(-(SIGNED_VALUE)num);
+
+ /* FIXNUM_MIN-1 .. LLONG_MIN mapped into 0xbfffffffffffffff .. LONG_MAX+1 */
+ if (v <= LLONG_MAX)
+ rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
+ return v;
+ }
return num;
}
diff --git a/test/-ext-/num2int/test_num2int.rb b/test/-ext-/num2int/test_num2int.rb
index 4e2dc37bfc..b27606288c 100644
--- a/test/-ext-/num2int/test_num2int.rb
+++ b/test/-ext-/num2int/test_num2int.rb
@@ -162,20 +162,11 @@ class TestNum2int < Test::Unit::TestCase
assert_output(ULLONG_MAX.to_s) do
Num2int.print_num2ull(-1)
end
- assert_output((LLONG_MAX+2).to_s) do
- Num2int.print_num2ull(LLONG_MIN+1)
- end
-
- # maybe bug
- assert_output((LLONG_MAX).to_s) do
- Num2int.print_num2ull(LLONG_MIN-1)
- end
- # maybe bug
- assert_output(1.to_s) do
- Num2int.print_num2ull(LLONG_MIN*2+1)
+ assert_output((LLONG_MAX+1).to_s) do
+ Num2int.print_num2ull(LLONG_MIN)
end
assert_raise(RangeError) do
- Num2int.print_num2ull(LLONG_MIN*2)
+ Num2int.print_num2ull(LLONG_MIN-1)
end
assert_raise(RangeError) do
Num2int.print_num2ull(ULLONG_MAX+1)