diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-12-13 10:22:57 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-12-13 10:29:16 +0900 |
| commit | 8a74b2a25d5a0b66326d9642567fef894ea90d10 (patch) | |
| tree | e62980da977db485c2e6ce148ae724fb8791f4cc | |
| parent | d01707d4cf53bef1121bc1c7c9ce735d28ab5be3 (diff) | |
| download | mruby-8a74b2a25d5a0b66326d9642567fef894ea90d10.tar.gz mruby-8a74b2a25d5a0b66326d9642567fef894ea90d10.zip | |
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.
| -rw-r--r-- | mrbgems/mruby-string-ext/src/string.c | 21 |
1 files 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; |
