summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2026-04-09 17:39:07 -0700
committerJohn Hawthorn <john@hawthorn.email>2026-04-26 17:14:39 +0900
commitf2d0ef269b47af7d0e658016903bd8917c32899a (patch)
tree637b3409b3a2cbf9fc6f07c6a27e851aca7f8f4a /object.c
parent96cd1bc765d84f896d063d29a8db33d82af2ac07 (diff)
Add and use rb_ivar_foreach_buffered
Previously, rb_ivar_foreach would walk up the shape tree, but yield instance variables to the callback as it went. If the object shape was modified during this callback, particularly with removing an instance variable, it could result in reading free'd memory. This commit solves this by adding a version which buffering all instance variable names and values before calling the callback, giving a snapshot of the object at the time rb_ivar_foreach_buffered is called. The buffer is made with ALLOCV_N, so the performance difference should be minimal, and I don't think this method is particuarly heavily used. [Bug #21996]
Diffstat (limited to 'object.c')
-rw-r--r--object.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/object.c b/object.c
index 706079141a..eaec5e89d2 100644
--- a/object.c
+++ b/object.c
@@ -769,7 +769,7 @@ inspect_obj(VALUE obj, VALUE a, int recur)
rb_str_cat2(str, " ...");
}
else {
- rb_ivar_foreach(obj, inspect_i, a);
+ rb_ivar_foreach_buffered(obj, inspect_i, a);
}
rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#';