summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2021-08-29 19:09:35 +0900
committernagachika <nagachika@ruby-lang.org>2021-08-29 19:09:35 +0900
commit8899fa0b3d41fd27dd1a2c6f75106cb78ff27236 (patch)
tree83ffd5adaa71a0d02735deb6f45d4cee8d481eb0
parent600d0f78395c6a67d6bc8974be9964701976e745 (diff)
merge revision(s) d43279edacd09edf3a43e02d62f5be475e7c3bcb,5dc36ddcd00fc556c04c15ce9770c5a84d7d43dc,523bf31564f160f899f8cf9f73540d6a6f687f17: [Backport #18138]
Fix length calculation for Array#slice! Commit 4f24255 introduced a bug which allows a length to be passed to rb_ary_new4 which is too large, resulting in invalid memory access. For example: (1..1000).to_a.slice!(-2, 1000) --- array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Add out of range tests for Array#slice! --- test/ruby/test_array.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) Add negative position tests [Bug #18138] --- test/ruby/test_array.rb | 4 ++++ 1 file changed, 4 insertions(+)
-rw-r--r--array.c2
-rw-r--r--test/ruby/test_array.rb17
-rw-r--r--version.h4
3 files changed, 20 insertions, 3 deletions
diff --git a/array.c b/array.c
index c0c8016813..7ed3b14ef5 100644
--- a/array.c
+++ b/array.c
@@ -4072,7 +4072,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
else if (orig_len < pos) {
return Qnil;
}
- else if (orig_len < pos + len) {
+ if (orig_len < pos + len) {
len = orig_len - pos;
}
if (len == 0) {
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 789531fb8c..26d40fcc6b 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -1563,6 +1563,8 @@ class TestArray < Test::Unit::TestCase
assert_nil(a.slice(10, -3))
assert_equal @cls[], a.slice(10..7)
+
+ assert_equal([100], a.slice(-1, 1_000_000_000))
end
def test_slice!
@@ -1611,6 +1613,21 @@ class TestArray < Test::Unit::TestCase
assert_raise(ArgumentError) { @cls[1].slice!(0, 0, 0) }
end
+ def test_slice_out_of_range!
+ a = @cls[*(1..100).to_a]
+
+ assert_nil(a.clone.slice!(-101..-1))
+ assert_nil(a.clone.slice!(-101..))
+
+ # assert_raise_with_message(RangeError, "((-101..-1).%(2)) out of range") { a.clone.slice!((-101..-1)%2) }
+ # assert_raise_with_message(RangeError, "((-101..).%(2)) out of range") { a.clone.slice!((-101..)%2) }
+
+ assert_nil(a.clone.slice!(10, -3))
+ assert_equal @cls[], a.clone.slice!(10..7)
+
+ assert_equal([100], a.clone.slice!(-1, 1_000_000_000))
+ end
+
def test_sort
a = @cls[ 4, 1, 2, 3 ]
assert_equal(@cls[1, 2, 3, 4], a.sort)
diff --git a/version.h b/version.h
index ca67d7f22a..8ba96bd2b7 100644
--- a/version.h
+++ b/version.h
@@ -12,11 +12,11 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 3
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 124
+#define RUBY_PATCHLEVEL 125
#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 8
-#define RUBY_RELEASE_DAY 19
+#define RUBY_RELEASE_DAY 29
#include "ruby/version.h"