aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-30 02:16:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-07-30 02:16:42 +0000
commit798b8d27916adcb3faa87e85e45211340b6bc3a4 (patch)
treee7dedaf7e6f870b1be663dde18505fadc6ff17c4
parent7e168983ce133427289d53d159a1e354abb4e92e (diff)
downloadruby-798b8d27916adcb3faa87e85e45211340b6bc3a4.tar.gz
* bignum.c (rb_big_aref): check for Bignum index range.
[ruby-dev:31271] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--bignum.c34
-rw-r--r--test/ruby/test_integer.rb7
-rw-r--r--version.h6
4 files changed, 37 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c08e24911..93532595fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul 30 11:16:40 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * bignum.c (rb_big_aref): check for Bignum index range.
+ [ruby-dev:31271]
+
Sat Jul 28 09:35:41 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
* ext/digest/lib/digest.rb (Digest::self.const_missing): avoid
diff --git a/bignum.c b/bignum.c
index a0402d7d2d..f4c2015c96 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2061,29 +2061,39 @@ static VALUE
rb_big_aref(VALUE x, VALUE y)
{
BDIGIT *xds;
- int shift;
- long s1, s2;
+ BDIGIT_DBL num;
+ VALUE shift;
+ long i, s1, s2;
if (TYPE(y) == T_BIGNUM) {
- if (!RBIGNUM(y)->sign || RBIGNUM(x)->sign)
+ if (!RBIGNUM(y)->sign)
return INT2FIX(0);
- return INT2FIX(1);
+ if (RBIGNUM(bigtrunc(y))->len > SIZEOF_VALUE/SIZEOF_BDIGITS) {
+ out_of_range:
+ return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(1);
+ }
+ shift = big2ulong(y, "long", Qfalse);
+ }
+ else {
+ i = NUM2LONG(y);
+ if (i < 0) return INT2FIX(0);
+ shift = (VALUE)i;
}
- shift = NUM2INT(y);
- if (shift < 0) return INT2FIX(0);
s1 = shift/BITSPERDIG;
s2 = shift%BITSPERDIG;
+ if (s1 >= RBIGNUM(x)->len) goto out_of_range;
if (!RBIGNUM(x)->sign) {
- if (s1 >= RBIGNUM(x)->len) return INT2FIX(1);
- x = rb_big_clone(x);
- get2comp(x);
+ xds = BDIGITS(x);
+ i = 0; num = 1;
+ while (num += ~xds[i], ++i <= s1) {
+ num = BIGDN(num);
+ }
}
else {
- if (s1 >= RBIGNUM(x)->len) return INT2FIX(0);
+ num = BDIGITS(x)[s1];
}
- xds = BDIGITS(x);
- if (xds[s1] & (1<<s2))
+ if (num & ((BDIGIT_DBL)1<<s2))
return INT2FIX(1);
return INT2FIX(0);
}
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index 2744f3df42..4ffe0c2fce 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -117,6 +117,13 @@ class TestInteger < Test::Unit::TestCase
end
}
}
+
+ # [ruby-dev:31271]
+ # assert_equal(1, (1 << 0x40000000)[0x40000000])
+ # assert_equal(0, (-1 << 0x40000001)[0x40000000])
+ big_zero = 0x40000000.coerce(0)[0]
+ assert_equal(0, (-0x40000002)[big_zero])
+ assert_equal(1, 0x400000001[big_zero])
end
def test_plus
diff --git a/version.h b/version.h
index ec7ee38f8d..8c57c87729 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-07-28"
+#define RUBY_RELEASE_DATE "2007-07-30"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20070728
+#define RUBY_RELEASE_CODE 20070730
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 7
-#define RUBY_RELEASE_DAY 28
+#define RUBY_RELEASE_DAY 30
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];