diff options
| author | nagachika <nagachika@ruby-lang.org> | 2023-09-24 15:13:32 +0900 |
|---|---|---|
| committer | nagachika <nagachika@ruby-lang.org> | 2023-09-24 15:13:32 +0900 |
| commit | 9ee58b2054c1bbe722ae5a2a4ec6a750ee583220 (patch) | |
| tree | 448b91bbf2b07702f8e61756f9d6ed050be63dc8 /vm_method.c | |
| parent | 9cd28caa7cc3b0d987db7c1231fe101fb3b27399 (diff) | |
merge revision(s) 96c5a4be7b0d72502001734770af0f4a735c544c: [Backport #19894]
Fix memory leak in complemented method entries
[Bug #19894]
When a copy of a complemented method entry is created, there are two
issues:
1. IMEMO_FL_USER3 is not copied, so the complemented status is not
copied over.
2. In rb_method_entry_clone we increment both alias_count and
complemented_count. However, when we free the method entry in
rb_method_definition_release, we only decrement one of the two
counters, resulting in the rb_method_definition_t being leaked.
Co-authored-by: Adam Hess <adamhess1991@gmail.com>
---
method.h | 5 +++--
test/ruby/test_module.rb | 29 +++++++++++++++++++++++++++++
vm_method.c | 8 +++++---
3 files changed, 37 insertions(+), 5 deletions(-)
Diffstat (limited to 'vm_method.c')
| -rw-r--r-- | vm_method.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/vm_method.c b/vm_method.c index 5f7264a53b..cb9f82304b 100644 --- a/vm_method.c +++ b/vm_method.c @@ -692,11 +692,13 @@ rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, c const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me) { - rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class, - method_definition_addref(src_me->def)); + rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class, src_me->def); if (METHOD_ENTRY_COMPLEMENTED(src_me)) { method_definition_addref_complement(src_me->def); } + else { + method_definition_addref(src_me->def); + } METHOD_ENTRY_FLAGS_COPY(me, src_me); return me; @@ -723,7 +725,7 @@ rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID cal def = NULL; } else { - def = method_definition_addref_complement(def); + method_definition_addref_complement(def); } me = rb_method_entry_alloc(called_id, src_me->owner, defined_class, def); METHOD_ENTRY_FLAGS_COPY(me, src_me); |
