From: Pietro Cerutti Date: Mon, 13 May 2019 11:42:37 +0000 (+0000) Subject: Do not cache a compiled regex to avoid leaks X-Git-Tag: 2019-10-25~209 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=264a5d403bca023c7b7aa96d85814d757f99c94a;p=neomutt Do not cache a compiled regex to avoid leaks glibc's implementation of the regex engine is a DFA which creates nodes on the fly under the regex_t object. This will cause leakes if we keep the compiled regular expression around, as it was the case before. See also https://sourceware.org/bugzilla/show_bug.cgi?id=12567 --- diff --git a/email/rfc2047.c b/email/rfc2047.c index 5857cb355..94b4e8da9 100644 --- a/email/rfc2047.c +++ b/email/rfc2047.c @@ -139,13 +139,9 @@ static size_t q_encoder(char *str, const char *buf, size_t buflen, const char *t static char *parse_encoded_word(char *str, enum ContentEncoding *enc, char **charset, size_t *charsetlen, char **text, size_t *textlen) { - static struct Regex *re = NULL; regmatch_t match[4]; size_t nmatch = 4; - - if (!re) - { - re = mutt_regex_compile("=\\?" + struct Regex *re = mutt_regex_compile("=\\?" "([^][()<>@,;:\\\"/?. =]+)" /* charset */ "\\?" "([qQbB])" /* encoding */ @@ -154,25 +150,28 @@ static char *parse_encoded_word(char *str, enum ContentEncoding *enc, char **cha as some mailers do that, see #1189. */ "\\?=", REG_EXTENDED); - assert(re && "Something is wrong with your RE engine."); - } + assert(re && "Something is wrong with your RE engine."); + char *res = NULL; int rc = regexec(re->regex, str, nmatch, match, 0); - if (rc != 0) - return NULL; - - /* Charset */ - *charset = str + match[1].rm_so; - *charsetlen = match[1].rm_eo - match[1].rm_so; - - /* Encoding: either Q or B */ - *enc = ((str[match[2].rm_so] == 'Q') || (str[match[2].rm_so] == 'q')) ? - ENC_QUOTED_PRINTABLE : - ENC_BASE64; + if (rc == 0) + { + /* Charset */ + *charset = str + match[1].rm_so; + *charsetlen = match[1].rm_eo - match[1].rm_so; + + /* Encoding: either Q or B */ + *enc = ((str[match[2].rm_so] == 'Q') || (str[match[2].rm_so] == 'q')) ? + ENC_QUOTED_PRINTABLE : + ENC_BASE64; + + *text = str + match[3].rm_so; + *textlen = match[3].rm_eo - match[3].rm_so; + res = str + match[0].rm_so; + } - *text = str + match[3].rm_so; - *textlen = match[3].rm_eo - match[3].rm_so; - return str + match[0].rm_so; + mutt_regex_free(&re); + return res; } /**