EMailStripSigFilter: Make sure it doesn't read out of buffer bounds

It could happen the reading of the buffer was done out of the buffer
bounds in some cases, as had been spotted in:
https://gitlab.gnome.org/GNOME/evolution/-/issues/1025#note_1470109

Related to https://gitlab.gnome.org/GNOME/evolution/-/issues/1156
This commit is contained in:
Milan Crha
2022-06-03 10:09:56 +02:00
parent a7fb3f64fc
commit 5f9d351472

View File

@ -32,7 +32,8 @@ G_DEFINE_TYPE (EMailStripSigFilter, e_mail_stripsig_filter, CAMEL_TYPE_MIME_FILT
static gboolean static gboolean
is_html_newline_marker (const gchar *text, is_html_newline_marker (const gchar *text,
gint len, gint len,
gint *advance_by_chars) gint *advance_by_chars,
gboolean *out_need_more_chars)
{ {
const gchar *cases[] = { const gchar *cases[] = {
"<br>", "<br>",
@ -48,10 +49,11 @@ is_html_newline_marker (const gchar *text,
NULL }; NULL };
gint ii; gint ii;
if (!text || !*text || !advance_by_chars) if (!text || !*text || !advance_by_chars || !out_need_more_chars)
return FALSE; return FALSE;
*advance_by_chars = 0; *advance_by_chars = 0;
*out_need_more_chars = FALSE;
for (ii = 0; cases[ii]; ii++) { for (ii = 0; cases[ii]; ii++) {
gint caselen = strlen (cases[ii]); gint caselen = strlen (cases[ii]);
@ -59,12 +61,17 @@ is_html_newline_marker (const gchar *text,
if (len >= caselen && g_ascii_strncasecmp (text, cases[ii], caselen) == 0) { if (len >= caselen && g_ascii_strncasecmp (text, cases[ii], caselen) == 0) {
if (cases[ii][caselen - 1] != '>') { if (cases[ii][caselen - 1] != '>') {
/* Need to find the tag end, in a lazy way */ /* Need to find the tag end, in a lazy way */
while (text[caselen] && text[caselen] != '>') while (caselen < len && text[caselen] && text[caselen] != '>')
caselen++; caselen++;
/* Advance after the '>' */ /* Advance after the '>' */
if (text[caselen]) if (caselen < len && text[caselen])
caselen++; caselen++;
if (caselen >= len) {
*out_need_more_chars = TRUE;
return FALSE;
}
} }
*advance_by_chars = caselen; *advance_by_chars = caselen;
@ -90,17 +97,23 @@ strip_signature (CamelMimeFilter *filter,
const gchar *inend = in + len; const gchar *inend = in + len;
const gchar *start = NULL; const gchar *start = NULL;
gint advance_by_chars = 0; gint advance_by_chars = 0;
gboolean need_more_chars = FALSE;
if (stripsig->midline) { if (stripsig->midline) {
while (inptr < inend && *inptr != '\n' && (stripsig->text_plain_only || while (inptr < inend && *inptr != '\n' && (stripsig->text_plain_only ||
!is_html_newline_marker (inptr, inend - inptr, &advance_by_chars))) !is_html_newline_marker (inptr, inend - inptr, &advance_by_chars, &need_more_chars))) {
if (need_more_chars && !flush)
goto read_more;
inptr++; inptr++;
}
if (!stripsig->text_plain_only && is_html_newline_marker (inptr, inend - inptr, &advance_by_chars)) { if (!stripsig->text_plain_only && is_html_newline_marker (inptr, inend - inptr, &advance_by_chars, &need_more_chars)) {
stripsig->midline = FALSE; stripsig->midline = FALSE;
inptr += advance_by_chars; inptr += advance_by_chars;
} else if (inptr < inend) { } else if (inptr < inend) {
stripsig->midline = FALSE; stripsig->midline = FALSE;
if (need_more_chars && !flush)
goto read_more;
inptr++; inptr++;
} }
} }
@ -116,16 +129,21 @@ strip_signature (CamelMimeFilter *filter,
inptr += 7; inptr += 7;
} else { } else {
while (inptr < inend && *inptr != '\n' && (stripsig->text_plain_only || while (inptr < inend && *inptr != '\n' && (stripsig->text_plain_only ||
!is_html_newline_marker (inptr, inend - inptr, &advance_by_chars))) !is_html_newline_marker (inptr, inend - inptr, &advance_by_chars, &need_more_chars))) {
if (need_more_chars && !flush)
goto read_more;
inptr++; inptr++;
}
if (inptr == inend) { if (inptr == inend) {
stripsig->midline = TRUE; stripsig->midline = TRUE;
break; break;
} }
if (!stripsig->text_plain_only && is_html_newline_marker (inptr, inend - inptr, &advance_by_chars)) if (!stripsig->text_plain_only && is_html_newline_marker (inptr, inend - inptr, &advance_by_chars, &need_more_chars))
inptr += advance_by_chars; inptr += advance_by_chars;
else if (need_more_chars && !flush)
goto read_more;
else else
inptr++; inptr++;
} }
@ -136,6 +154,7 @@ strip_signature (CamelMimeFilter *filter,
stripsig->midline = FALSE; stripsig->midline = FALSE;
} }
read_more:
if (!flush && inend > inptr) if (!flush && inend > inptr)
camel_mime_filter_backup (filter, inptr, inend - inptr); camel_mime_filter_backup (filter, inptr, inend - inptr);
else if (!start) else if (!start)