Skip to content

Commit b2bb029

Browse files
committed
merge revision(s) 50827,50921: [Backport ruby#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 ruby#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
1 parent e9ea9d6 commit b2bb029

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
Mon Aug 17 16:18:13 2015 Nobuyoshi Nakada <[email protected]>
2+
3+
* array.c (ary_ensure_room_for_push): check if array size will
4+
exceed maximum size to get rid of buffer overflow.
5+
[ruby-dev:49043] [Bug #11235]
6+
7+
* array.c (ary_ensure_room_for_unshift, rb_ary_splice): ditto.
8+
19
Mon Aug 17 16:14:38 2015 Nobuyoshi Nakada <[email protected]>
210

311
* ext/win32/lib/win32/registry.rb (Win32::Registry::API): use wide

array.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,13 @@ rb_ary_modify(VALUE ary)
354354
static void
355355
ary_ensure_room_for_push(VALUE ary, long add_len)
356356
{
357-
long new_len = RARRAY_LEN(ary) + add_len;
357+
long old_len = RARRAY_LEN(ary);
358+
long new_len = old_len + add_len;
358359
long capa;
359360

361+
if (old_len > ARY_MAX_SIZE - add_len) {
362+
rb_raise(rb_eIndexError, "index %ld too big", new_len);
363+
}
360364
if (ARY_SHARED_P(ary)) {
361365
if (new_len > RARRAY_EMBED_LEN_MAX) {
362366
VALUE shared = ARY_SHARED(ary);
@@ -1078,6 +1082,10 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
10781082
long capa;
10791083
const VALUE *head, *sharedp;
10801084

1085+
if (len > ARY_MAX_SIZE - argc) {
1086+
rb_raise(rb_eIndexError, "index %ld too big", new_len);
1087+
}
1088+
10811089
if (ARY_SHARED_P(ary)) {
10821090
VALUE shared = ARY_SHARED(ary);
10831091
capa = RARRAY_LEN(shared);
@@ -1569,6 +1577,9 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
15691577
else {
15701578
long alen;
15711579

1580+
if (olen - len > ARY_MAX_SIZE - rlen) {
1581+
rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
1582+
}
15721583
rb_ary_modify(ary);
15731584
alen = olen + rlen - len;
15741585
if (alen >= ARY_CAPA(ary)) {

test/ruby/test_array.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,4 +2477,32 @@ def test_shared_marking
24772477
skip e.message
24782478
end
24792479
end
2480+
2481+
sizeof_long = [0].pack("l!").size
2482+
sizeof_voidp = [""].pack("p").size
2483+
if sizeof_long < sizeof_voidp
2484+
ARY_MAX = (1<<(8*sizeof_long-1)) / sizeof_voidp - 1
2485+
Bug11235 = '[ruby-dev:49043] [Bug #11235]'
2486+
2487+
def test_push_over_ary_max
2488+
assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;")
2489+
a = Array.new(ARGV[0].to_i)
2490+
assert_raise(IndexError, ARGV[1]) {0x1000.times {a.push(1)}}
2491+
end;
2492+
end
2493+
2494+
def test_unshift_over_ary_max
2495+
assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;")
2496+
a = Array.new(ARGV[0].to_i)
2497+
assert_raise(IndexError, ARGV[1]) {0x1000.times {a.unshift(1)}}
2498+
end;
2499+
end
2500+
2501+
def test_splice_over_ary_max
2502+
assert_separately(['-', ARY_MAX.to_s, Bug11235], <<-"end;")
2503+
a = Array.new(ARGV[0].to_i)
2504+
assert_raise(IndexError, ARGV[1]) {a[0, 0] = Array.new(0x1000)}
2505+
end;
2506+
end
2507+
end
24802508
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.1.7"
22
#define RUBY_RELEASE_DATE "2015-08-17"
3-
#define RUBY_PATCHLEVEL 380
3+
#define RUBY_PATCHLEVEL 381
44

55
#define RUBY_RELEASE_YEAR 2015
66
#define RUBY_RELEASE_MONTH 8

0 commit comments

Comments
 (0)