diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-09-20 10:29:24 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-09-20 10:49:49 +0900 |
commit | 422ae594d97e803e829e65716e85483f5942e0c3 (patch) | |
tree | c353dace43deee21d67b5c62435de95518225fcc /array.c | |
parent | 45bac6284595834b68a34f4f4efe5880436fce11 (diff) |
Fixed memory leak
* array.c (flatten): fix a memory leak in the case of an exception
at conversion of an element to Array.
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -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; |