summaryrefslogtreecommitdiff
path: root/shape.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-11-14 10:24:55 -0500
committerPeter Zhu <peter@peterzhu.ca>2022-11-15 08:53:46 -0500
commit5dcbe5883364c763ca5324e40716a334360c19a7 (patch)
treec69f3cba0106f5b0c92418cc4cb6cc7ecb197099 /shape.c
parent36dc99af5aa3932f3a85b1d8212e1d3625307a90 (diff)
downloadruby-5dcbe5883364c763ca5324e40716a334360c19a7.tar.gz
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
Diffstat (limited to 'shape.c')
-rw-r--r--shape.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/shape.c b/shape.c
index 66f5f69a0c..736f37c98b 100644
--- a/shape.c
+++ b/shape.c
@@ -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);
}