summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-12-16 11:39:35 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-12-16 11:39:35 +0900
commit57d93c4d762a3214c48928c9df6223eb86caa343 (patch)
tree51e6b3344f71206a0c119c39cc44db9b904fb0cd
parent0fbdd71dcf9c1608587a13aee424fe30270fd0f4 (diff)
downloadmruby-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.c44
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);