summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-16 18:50:47 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-16 18:50:47 +0000
commit47f64f1ea1eaaa6c37762cbc629ae46333cb3820 (patch)
treea9eca6790750d50cec93eadb9d8d8ee13ee11dc7
parent2e4b5a32f27d46494198c8e1f62da2c5abb9c883 (diff)
merge revision(s) 56938: [Backport #12988]
Stop reading past the end of `ivptr` array If you have code like this: ```ruby class A def initialize @a = nil @b = nil @c = nil @d = nil @e = nil end end x = A.new y = x.clone 100.times { |z| x.instance_variable_set(:"@foo#{z}", nil) } puts y.inspect ``` `x` and `y` will share `iv_index_tbl` hashes. However, the size of the hash will grow larger than the number if entries in `ivptr` in `y`. Before this commit, `rb_ivar_count` would use the size of the hash to determine how far to read in to the array, but this means that it could read past the end of the array and cause the program to segv [ruby-core:78403] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@57341 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--variable.c2
-rw-r--r--version.h2
2 files changed, 2 insertions, 2 deletions
diff --git a/variable.c b/variable.c
index 618aa852bd..2b8ee6672b 100644
--- a/variable.c
+++ b/variable.c
@@ -1605,7 +1605,7 @@ rb_ivar_count(VALUE obj)
switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
- st_index_t i, count, num = tbl->num_entries;
+ st_index_t i, count, num = ROBJECT_NUMIV(obj);
const VALUE *const ivptr = ROBJECT_IVPTR(obj);
for (i = count = 0; i < num; ++i) {
if (ivptr[i] != Qundef) {
diff --git a/version.h b/version.h
index 760766a397..c99d4abebb 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.3.3"
#define RUBY_RELEASE_DATE "2017-01-17"
-#define RUBY_PATCHLEVEL 225
+#define RUBY_PATCHLEVEL 226
#define RUBY_RELEASE_YEAR 2017
#define RUBY_RELEASE_MONTH 1