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.
parent d01707d4
...@@ -307,13 +307,12 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte ...@@ -307,13 +307,12 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
pat1 = ret_uninit pat1 = ret_uninit
? ret ? ret
: (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern)); : (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern));
if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') { if (pat1 == NULL) {
if (pat1 == NULL && ret) {
nomem:
tr_free_pattern(mrb, ret); tr_free_pattern(mrb, ret);
mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
return NULL; /* not reached */ return NULL; /* not reached */
} }
if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') {
pat1->type = TR_RANGE; pat1->type = TR_RANGE;
pat1->flag_reverse = flag_reverse; pat1->flag_reverse = flag_reverse;
pat1->flag_on_heap = !ret_uninit; 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 ...@@ -336,11 +335,10 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
len = i - start_pos; len = i - start_pos;
if (len > UINT16_MAX) { 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)"); mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65535)");
} }
if (pat1 == NULL && ret) {
goto nomem;
}
pat1->type = TR_IN_ORDER; pat1->type = TR_IN_ORDER;
pat1->flag_reverse = flag_reverse; pat1->flag_reverse = flag_reverse;
pat1->flag_on_heap = !ret_uninit; 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 ...@@ -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; pat1->val.start_pos = (uint16_t)start_pos;
} }
if (ret == NULL || ret_uninit) { if (!ret_uninit) {
ret = pat1;
}
else {
struct tr_pattern *p = ret; struct tr_pattern *p = ret;
while (p->next != NULL) { while (p->next != NULL) {
p = p->next; p = p->next;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment