From 8a74b2a25d5a0b66326d9642567fef894ea90d10 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Dec 2021 10:22:57 +0900 Subject: string-ext/string.c: fixed memory leak from `tr` on exception. With some refactoring. * `ret` argument is always non-nil, so no check needed. * move allocation check right after malloc(). * simplify conditions. --- mrbgems/mruby-string-ext/src/string.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index eaeb48247..2c4fed4e9 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -307,13 +307,12 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte pat1 = ret_uninit ? ret : (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern)); + if (pat1 == NULL) { + tr_free_pattern(mrb, ret); + mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); + return NULL; /* not reached */ + } if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') { - if (pat1 == NULL && ret) { - nomem: - tr_free_pattern(mrb, ret); - mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); - return NULL; /* not reached */ - } pat1->type = TR_RANGE; pat1->flag_reverse = flag_reverse; pat1->flag_on_heap = !ret_uninit; @@ -336,11 +335,10 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte len = i - start_pos; if (len > UINT16_MAX) { + tr_free_pattern(mrb, ret); + if (ret != pat1) mrb_free(mrb, pat1); mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65535)"); } - if (pat1 == NULL && ret) { - goto nomem; - } pat1->type = TR_IN_ORDER; pat1->flag_reverse = flag_reverse; pat1->flag_on_heap = !ret_uninit; @@ -349,10 +347,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte pat1->val.start_pos = (uint16_t)start_pos; } - if (ret == NULL || ret_uninit) { - ret = pat1; - } - else { + if (!ret_uninit) { struct tr_pattern *p = ret; while (p->next != NULL) { p = p->next; -- cgit v1.2.3