October 6, 2005
12:32 AM

I've been getting pretty deep with the Ruby source code lately.

In array.c (1.8.2) I found this gem:

static VALUE rb_ary_rindex(ary, val)
    VALUE ary;
    VALUE val;
{
    long i = RARRAY(ary)->len;

    while (i--) {
        if (i > RARRAY(ary)->len) {
            i = RARRAY(ary)->len;
            continue;
        }
        if (rb_equal(RARRAY(ary)->ptr[i], val))
            return LONG2NUM(i);
    }
    return Qnil;
}
Crafting some interesting ruby code:
class F
    def ==(obj)
        puts "hi from F!"
        abort
    end
end

class T
    def ==(obj)
        @array[1] = F.new
        @array.clear
        puts "F is no more?" if (@array == [])
        @array[0] = nil        
        false
    end
       
    def make
        @array = [self, self, self]
    end
end

T.new.make.rindex(nil)

We produce the output:

F is no more?
hi from F!

Effectively an out of bounds array access. Not overly serious (and not difficult to fix). In any case it appears this code has been cleaned up in the source available via cvs.

© Douglas Stockwell 2007
Creative Commons License Unless otherwise specified all "source code" examples are available for use under the Creative Commons Attribution-Noncommercial 3.0 License. Please contact me if you would like more flexible licensing terms.
Messenger Presence