git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 2/5] mailinfo: warn if CR found in base64/quoted-printable email

From
Junio C Hamano <gitster@pobox.com>
Date
May 5, 2021, 03:41 UTC
Message-ID
<xmqqr1il4zk0.fsf@gitster.g>
In-Reply-To
<45d2c4ab58c4b0c6f0c7790890bbf75eb373f999.1620148732.git.congdanhqx@gmail.com>
Đoàn Trần Công Danh  <congdanhqx@gmail.com> writes:
> When an SMTP server receives an 8-bit email message, possibly with only
> LF as line ending, some of those servers decide to change said LF to
> CRLF.

s/an SMTP server receives/SMTP servers receive/ s/those servers/them/

> Some mailing list softwares, when receives an 8-bit email message,
> decide to encoding such message in base64 or quoted-printable.
s/encoding/encode/

So the issue is not about CRLF terminating the lines of base64 or QP (we should treat CRLF and LF terminated lines when unwrapping base64 or QP the same way). It is about seeing CRLF in the payload after unwrapping base64 or QP. It was unclear which one was at issue from the subject alone.

Show 7 quoted lines
> If an email is transfered through above mail servers, then distributed
> by such mailing list softwares, the recipients will receive an email
> contains a patch mungled with CRLF encoded inside another encoding.
> Thus, such CR couldn't be dropped by mailsplit. Hence, the mailed patch
> couldn't be applied cleanly. Such accidents have been observed in the wild [1].
>
> Let's give our users some warnings if such CR is found.

Hmph. It is unclear which one of the following we want our endgame to be:

 (1) strip silently and apply
 (2) warn but strip and apply
 (3) warn but do not strip, letting the application fail

but let's keep reading. I suspect (1) and (2) might be error prone, as the mailpath that may have caused this kind of breakage may not be under end-user's control.

Show 5 quoted lines
> +static void summarize_quoted_cr(struct mailinfo *mi, int have_quoted_cr)
> +{
> +	if (have_quoted_cr)
> +		warning("quoted CR detected");
> +}

At this step, it is unclear if it is easier to read to make it the responsibility of the caller to check for have_quoted_cr, but it will become clear as we add more condition for the warning in later steps to let callers unconditionally call this helper and decide when we want to be silent inside this function.

Have you considered adding a new have_quoted_cr member to "struct mailinfo"? After all, the mailinfo struct is not only about end user preference but contains all information we gleaned out of the incoming message.

Show 51 quoted lines
>  static void handle_body(struct mailinfo *mi, struct strbuf *line)
>  {
>  	struct strbuf prev = STRBUF_INIT;
> +	int have_quoted_cr = 0;
>  
>  	/* Skip up to the first boundary */
>  	if (*(mi->content_top)) {
> @@ -1051,6 +1063,8 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
>  				handle_filter(mi, &prev);
>  				strbuf_reset(&prev);
>  			}
> +			summarize_quoted_cr(mi, have_quoted_cr);
> +			have_quoted_cr = 0;
>  			if (!handle_boundary(mi, line))
>  				goto handle_body_out;
>  		}
> @@ -1081,7 +1095,7 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
>  						strbuf_addbuf(&prev, sb);
>  						break;
>  					}
> -				handle_filter_flowed(mi, sb, &prev);
> +				handle_filter_flowed(mi, sb, &prev, &have_quoted_cr);
>  			}
>  			/*
>  			 * The partial chunk is saved in "prev" and will be
> @@ -1091,7 +1105,7 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
>  			break;
>  		}
>  		default:
> -			handle_filter_flowed(mi, line, &prev);
> +			handle_filter_flowed(mi, line, &prev, &have_quoted_cr);
>  		}
>  
>  		if (mi->input_error)
> @@ -1100,6 +1114,7 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
>  
>  	if (prev.len)
>  		handle_filter(mi, &prev);
> +	summarize_quoted_cr(mi, have_quoted_cr);
>  
>  	flush_inbody_header_accum(mi);
>  
> diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh
> index 147e616533..d8fdda6bea 100755
> --- a/t/t5100-mailinfo.sh
> +++ b/t/t5100-mailinfo.sh
> @@ -228,4 +228,19 @@ test_expect_success 'mailinfo handles unusual header whitespace' '
>  	test_cmp expect actual
>  '
>  
> +check_quoted_cr_mail() {
SP on both sides of (), i.e.
	check_quoted_cr_mail () {
Show 15 quoted lines
> +	git mailinfo -u "$@" quoted-cr-msg quoted-cr-patch \
> +		<"$DATA/quoted-cr.mbox" >quoted-cr-info 2>quoted-cr-err &&
> +	test_cmp "expect-cr-msg" quoted-cr-msg &&
> +	test_cmp "expect-cr-patch" quoted-cr-patch &&
> +	test_cmp "$DATA/quoted-cr-info" quoted-cr-info
> +}
> +
> +test_expect_success 'mailinfo warn CR in base64 encoded email' '
> +	sed "s/%%/$(printf \\015)/" "$DATA/quoted-cr-msg" >expect-cr-msg &&
> +	sed "s/%%/$(printf \\015)/" "$DATA/quoted-cr-patch" >expect-cr-patch &&
> +	check_quoted_cr_mail &&
> +	grep "quoted CR detected" quoted-cr-err
> +'
> +
>  test_done
Previous: Đoàn Trần Công DanhNext: Đoàn Trần Công Danh
Message 9 of 35 in “mailinfo: strip CR from base64/quoted-printable email”
  1. mailinfo: strip CR from base64/quoted-printable emailĐoàn Trần Công Danh, Apr 21, 2021
  2. Junio C HamanoApr 21, 2021
  3. brian m. carlsonApr 21, 2021
  4. Đoàn Trần Công DanhApr 21, 2021
  5. brian m. carlsonApr 22, 2021
  6. 0/5 Teach am/mailinfo to process quoted CRĐoàn Trần Công Danh, May 4, 2021
  7. 1/5 mailinfo: avoid magic number in option parsingĐoàn Trần Công Danh, May 4, 2021
  8. 2/5 mailinfo: warn if CR found in base64/quoted-printable emailĐoàn Trần Công Danh, May 4, 2021
  9. Junio C HamanoMay 5, 2021
  10. 3/5 mailinfo: skip quoted CR on user's wishĐoàn Trần Công Danh, May 4, 2021
  11. Junio C HamanoMay 5, 2021
  12. Đoàn Trần Công DanhMay 5, 2021
  13. 4/5 mailinfo: strip quoted CR on users' wishĐoàn Trần Công Danh, May 4, 2021
  14. Junio C HamanoMay 5, 2021
  15. 5/5 am: learn to process quoted lines that ends with CRLFĐoàn Trần Công Danh, May 4, 2021
  16. Junio C HamanoMay 5, 2021
  17. 0/6 Teach am/mailinfo to process quoted CRĐoàn Trần Công Danh, May 6, 2021
  18. 1/6 mailinfo: load default metainfo_charset lazilyĐoàn Trần Công Danh, May 6, 2021
  19. 2/6 mailinfo: stop parsing options manuallyĐoàn Trần Công Danh, May 6, 2021
  20. Junio C HamanoMay 8, 2021
  21. 3/6 mailinfo: warn if CR found in decoded base64/QP emailĐoàn Trần Công Danh, May 6, 2021
  22. Junio C HamanoMay 8, 2021
  23. 4/6 mailinfo: allow squelching quoted CR warningĐoàn Trần Công Danh, May 6, 2021
  24. 5/6 mailinfo: allow stripping quoted CR without warningĐoàn Trần Công Danh, May 6, 2021
  25. 6/6 am: learn to process quoted lines that ends with CRLFĐoàn Trần Công Danh, May 6, 2021
  26. Junio C HamanoMay 8, 2021
  27. 0/6 Teach am/mailinfo to process quoted CRĐoàn Trần Công Danh, May 9, 2021
  28. 1/6 mailinfo: load default metainfo_charset lazilyĐoàn Trần Công Danh, May 9, 2021
  29. 2/6 mailinfo: stop parsing options manuallyĐoàn Trần Công Danh, May 9, 2021
  30. 3/6 mailinfo: warn if CRLF found in decoded base64/QP emailĐoàn Trần Công Danh, May 9, 2021
  31. 4/6 mailinfo: allow squelching quoted CRLF warningĐoàn Trần Công Danh, May 9, 2021
  32. 5/6 mailinfo: allow stripping quoted CR without warningĐoàn Trần Công Danh, May 9, 2021
  33. 6/6 am: learn to process quoted lines that ends with CRLFĐoàn Trần Công Danh, May 9, 2021
  34. 2/6 mailinfo: stop parse options manuallyĐoàn Trần Công Danh, May 6, 2021
  35. Đoàn Trần Công DanhMay 6, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.