diff options
author | Peter Zhu <[email protected]> | 2022-11-14 10:24:55 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2022-11-15 08:53:46 -0500 |
commit | 5dcbe5883364c763ca5324e40716a334360c19a7 (patch) | |
tree | c69f3cba0106f5b0c92418cc4cb6cc7ecb197099 | |
parent | 36dc99af5aa3932f3a85b1d8212e1d3625307a90 (diff) |
Fix buffer overrun in ivars when rebuilding shapes
In rb_shape_rebuild_shape, we need to increase the capacity when
capacity == next_iv_index since the next ivar will be writing at index
next_iv_index.
This bug can be reproduced when assertions are turned on and you run the
following code:
class Foo
def initialize
@a1 = 1
@a2 = 1
@a3 = 1
@a4 = 1
@a5 = 1
@a6 = 1
@a7 = 1
end
def add_ivars
@a8 = 1
@a9 = 1
end
end
class Bar < Foo
end
foo = Foo.new
foo.add_ivars
bar = Bar.new
GC.start
bar.add_ivars
bar.clone
You will get the following crash:
Assertion Failed: object.c:301:rb_obj_copy_ivar:src_num_ivs <= shape_to_set_on_dest->capacity
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6725
-rw-r--r-- | shape.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -342,7 +342,7 @@ rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape) switch (dest_shape->type) { case SHAPE_IVAR: - if (midway_shape->capacity < midway_shape->next_iv_index) { + if (midway_shape->capacity <= midway_shape->next_iv_index) { // There isn't enough room to write this IV, so we need to increase the capacity midway_shape = rb_shape_transition_shape_capa(midway_shape, midway_shape->capacity * 2); } |