summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-09-20 10:29:24 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-09-20 10:49:49 +0900
commit422ae594d97e803e829e65716e85483f5942e0c3 (patch)
treec353dace43deee21d67b5c62435de95518225fcc
parent45bac6284595834b68a34f4f4efe5880436fce11 (diff)
Fixed memory leak
* array.c (flatten): fix a memory leak in the case of an exception at conversion of an element to Array.
-rw-r--r--array.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/array.c b/array.c
index 55b408e43f..68f9321192 100644
--- a/array.c
+++ b/array.c
@@ -5119,13 +5119,16 @@ static VALUE
flatten(VALUE ary, int level, int *modified)
{
long i = 0;
- VALUE stack, result, tmp, elt;
+ VALUE stack, result, tmp, elt, vmemo;
st_table *memo;
st_data_t id;
stack = ary_new(0, ARY_DEFAULT_SIZE);
result = ary_new(0, RARRAY_LEN(ary));
+ vmemo = rb_hash_new();
+ RBASIC_CLEAR_CLASS(vmemo);
memo = st_init_numtable();
+ rb_hash_st_table_set(vmemo, memo);
st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
*modified = 0;
@@ -5138,6 +5141,8 @@ flatten(VALUE ary, int level, int *modified)
}
tmp = rb_check_array_type(elt);
if (RBASIC(result)->klass) {
+ RB_GC_GUARD(vmemo);
+ st_clear(memo);
rb_raise(rb_eRuntimeError, "flatten reentered");
}
if (NIL_P(tmp)) {
@@ -5147,7 +5152,7 @@ flatten(VALUE ary, int level, int *modified)
*modified = 1;
id = (st_data_t)tmp;
if (st_lookup(memo, id, 0)) {
- st_free_table(memo);
+ st_clear(memo);
rb_raise(rb_eArgError, "tried to flatten recursive array");
}
st_insert(memo, id, (st_data_t)Qtrue);
@@ -5167,7 +5172,7 @@ flatten(VALUE ary, int level, int *modified)
ary = rb_ary_pop(stack);
}
- st_free_table(memo);
+ st_clear(memo);
RBASIC_SET_CLASS(result, rb_obj_class(ary));
return result;