mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
string-ext.c: fix memory leak in tr_parse_pattern.
This commit is contained in:
@@ -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) {
|
||||
j--;
|
||||
}
|
||||
else {
|
||||
mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n);
|
||||
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 < 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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user