string-ext.c: fix memory leak in `tr_parse_pattern`.

parent 0fbdd71d
......@@ -288,7 +288,7 @@ tr_free_pattern(mrb_state *mrb, struct tr_pattern *pat)
}
static struct tr_pattern*
tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable)
tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable, struct tr_pattern *pat0)
{
const char *pattern = RSTRING_PTR(v_pattern);
mrb_int pattern_length = RSTRING_LEN(v_pattern);
......@@ -308,6 +308,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
? ret
: (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern));
if (pat1 == NULL) {
if (pat0) tr_free_pattern(mrb, pat0);
tr_free_pattern(mrb, ret);
mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
return NULL; /* not reached */
......@@ -335,6 +336,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte
len = i - start_pos;
if (len > UINT16_MAX) {
if (pat0) tr_free_pattern(mrb, pat0);
tr_free_pattern(mrb, ret);
if (ret != pat1) mrb_free(mrb, pat1);
mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65535)");
......@@ -482,18 +484,17 @@ static mrb_bool
str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squeeze)
{
struct tr_pattern pat = STATIC_TR_PATTERN;
struct tr_pattern rep_storage = STATIC_TR_PATTERN;
struct tr_pattern rep = STATIC_TR_PATTERN;
char *s;
mrb_int len;
mrb_int i;
mrb_int j;
mrb_bool flag_changed = FALSE;
mrb_int lastch = -1;
struct tr_pattern *rep;
mrb_str_modify(mrb, mrb_str_ptr(str));
tr_parse_pattern(mrb, &pat, p1, TRUE);
rep = tr_parse_pattern(mrb, &rep_storage, p2, FALSE);
tr_parse_pattern(mrb, &pat, p1, TRUE, NULL);
tr_parse_pattern(mrb, &rep, p2, FALSE, &pat);
s = RSTRING_PTR(str);
len = RSTRING_LEN(str);
......@@ -503,29 +504,24 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee
if (i>j) s[j] = s[i];
if (n >= 0) {
flag_changed = TRUE;
if (rep == NULL) {
mrb_int c = tr_get_character(&rep, RSTRING_PTR(p2), n);
if (c < 0 || (squeeze && c == lastch)) {
j--;
continue;
}
else {
mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n);
if (c < 0 || (squeeze && c == lastch)) {
j--;
continue;
}
if (c > 0x80) {
tr_free_pattern(mrb, &pat);
tr_free_pattern(mrb, rep);
mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c);
}
lastch = c;
s[i] = (char)c;
if (c > 0x80) {
tr_free_pattern(mrb, &pat);
tr_free_pattern(mrb, &rep);
mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c);
}
lastch = c;
s[i] = (char)c;
}
}
tr_free_pattern(mrb, &pat);
tr_free_pattern(mrb, rep);
tr_free_pattern(mrb, &rep);
if (flag_changed) {
RSTR_SET_LEN(RSTRING(str), j);
......@@ -658,7 +654,7 @@ str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat)
mrb_str_modify(mrb, mrb_str_ptr(str));
if (!mrb_nil_p(v_pat)) {
pat = tr_parse_pattern(mrb, &pat_storage, v_pat, TRUE);
pat = tr_parse_pattern(mrb, &pat_storage, v_pat, TRUE, NULL);
tr_compile_pattern(pat, v_pat, bitmap);
tr_free_pattern(mrb, pat);
}
......@@ -749,7 +745,7 @@ str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat)
uint8_t bitmap[32];
mrb_str_modify(mrb, mrb_str_ptr(str));
tr_parse_pattern(mrb, &pat, v_pat, TRUE);
tr_parse_pattern(mrb, &pat, v_pat, TRUE, NULL);
tr_compile_pattern(&pat, v_pat, bitmap);
tr_free_pattern(mrb, &pat);
......@@ -817,7 +813,7 @@ mrb_str_count(mrb_state *mrb, mrb_value str)
uint8_t bitmap[32];
mrb_get_args(mrb, "S", &v_pat);
tr_parse_pattern(mrb, &pat, v_pat, TRUE);
tr_parse_pattern(mrb, &pat, v_pat, TRUE, NULL);
tr_compile_pattern(&pat, v_pat, bitmap);
tr_free_pattern(mrb, &pat);
......
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