diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-12-16 11:39:35 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-12-16 11:39:35 +0900 |
| commit | 57d93c4d762a3214c48928c9df6223eb86caa343 (patch) | |
| tree | 51e6b3344f71206a0c119c39cc44db9b904fb0cd | |
| parent | 0fbdd71dcf9c1608587a13aee424fe30270fd0f4 (diff) | |
| download | mruby-57d93c4d762a3214c48928c9df6223eb86caa343.tar.gz mruby-57d93c4d762a3214c48928c9df6223eb86caa343.zip | |
string-ext.c: fix memory leak in `tr_parse_pattern`.
| -rw-r--r-- | mrbgems/mruby-string-ext/src/string.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 2c4fed4e9..8360a051c 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -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); |
