diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-08-17 07:21:29 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-08-17 07:21:29 +0000 |
commit | b2bb02940199c3a540e903e9bb5b31abbf26f4aa (patch) | |
tree | a118f29872e80bc968292ed9533c8823f057fcfa | |
parent | e9ea9d6527b1f1db455d89ce6e5b6c3cfa40a184 (diff) |
merge revision(s) 50827,50921: [Backport #11235]
* array.c (ary_ensure_room_for_push): check if array size will
exceed maxmum size to get rid of buffer overflow.
[ruby-dev:49043] [Bug #11235]
* array.c (ary_ensure_room_for_unshift, rb_ary_splice): ditto.
exceed maximum size to get rid of buffer overflow.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@51597 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | array.c | 13 | ||||
-rw-r--r-- | test/ruby/test_array.rb | 28 | ||||
-rw-r--r-- | version.h | 2 |
4 files changed, 49 insertions, 2 deletions
@@ -1,3 +1,11 @@ +Mon Aug 17 16:18:13 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * array.c (ary_ensure_room_for_push): check if array size will + exceed maximum size to get rid of buffer overflow. + [ruby-dev:49043] [Bug #11235] + + * array.c (ary_ensure_room_for_unshift, rb_ary_splice): ditto. + Mon Aug 17 16:14:38 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> * ext/win32/lib/win32/registry.rb (Win32::Registry::API): use wide @@ -354,9 +354,13 @@ rb_ary_modify(VALUE ary) static void ary_ensure_room_for_push(VALUE ary, long add_len) { - long new_len = RARRAY_LEN(ary) + add_len; + long old_len = RARRAY_LEN(ary); + long new_len = old_len + add_len; long capa; + if (old_len > ARY_MAX_SIZE - add_len) { + rb_raise(rb_eIndexError, "index %ld too big", new_len); + } if (ARY_SHARED_P(ary)) { if (new_len > RARRAY_EMBED_LEN_MAX) { VALUE shared = ARY_SHARED(ary); @@ -1078,6 +1082,10 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) long capa; const VALUE *head, *sharedp; + if (len > ARY_MAX_SIZE - argc) { + rb_raise(rb_eIndexError, "index %ld too big", new_len); + } + if (ARY_SHARED_P(ary)) { VALUE shared = ARY_SHARED(ary); capa = RARRAY_LEN(shared); @@ -1569,6 +1577,9 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl) else { long alen; + if (olen - len > ARY_MAX_SIZE - rlen) { + rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len); + } rb_ary_modify(ary); alen = olen + rlen - len; if (alen >= ARY_CAPA(ary)) { diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 6e1316dc07..f10023edfd 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -2477,4 +2477,32 @@ class TestArray < Test::Unit::TestCase skip e.message end end + + sizeof_long = [0].pack("l!").size + sizeof_voidp = [""].pack("p").size + if sizeof_long < sizeof_voidp + ARY_MAX = (1<<(8*sizeof_long-1)) / sizeof_voidp - 1 + Bug11235 = '[ruby-dev:49043] [Bug #11235]' + + def test_push_over_ary_max + assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;") + a = Array.new(ARGV[0].to_i) + assert_raise(IndexError, ARGV[1]) {0x1000.times {a.push(1)}} + end; + end + + def test_unshift_over_ary_max + assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;") + a = Array.new(ARGV[0].to_i) + assert_raise(IndexError, ARGV[1]) {0x1000.times {a.unshift(1)}} + end; + end + + def test_splice_over_ary_max + assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;") + a = Array.new(ARGV[0].to_i) + assert_raise(IndexError, ARGV[1]) {a[0, 0] = Array.new(0x1000)} + end; + end + end end @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.1.7" #define RUBY_RELEASE_DATE "2015-08-17" -#define RUBY_PATCHLEVEL 380 +#define RUBY_PATCHLEVEL 381 #define RUBY_RELEASE_YEAR 2015 #define RUBY_RELEASE_MONTH 8 |