[前][次][番号順一覧][スレッド一覧]

ruby-changes:44865

From: tenderlove <ko1@a...>
Date: Wed, 30 Nov 2016 02:06:40 +0900 (JST)
Subject: [ruby-changes:44865] tenderlove:r56938 (trunk): Stop reading past the end of `ivptr` array

tenderlove	2016-11-30 02:06:35 +0900 (Wed, 30 Nov 2016)

  New Revision: 56938

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56938

  Log:
    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]

  Modified files:
    trunk/variable.c
Index: variable.c
===================================================================
--- variable.c	(revision 56937)
+++ variable.c	(revision 56938)
@@ -1619,7 +1619,7 @@ rb_ivar_count(VALUE obj) https://github.com/ruby/ruby/blob/trunk/variable.c#L1619
     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) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]