From: Eric Wong Date: Fri, 20 Apr 2018 03:27:37 +0000 (+0000) Subject: disallow "\t" and "\n" in OVER headers X-Git-Tag: v1.1.0-pre1~17 X-Git-Url: http://www.git.stargrave.org/?p=public-inbox.git;a=commitdiff_plain;h=0ef5872cee83f07c9ae7afceb2e92257507dc3ca disallow "\t" and "\n" in OVER headers For Subject/To/Cc/From headers, we squeeze them to a space (' '). For Message-IDs (including References/In-Reply-To), '\t', '\n', '\r' are deleted since some MUAs might screw them up: https://public-inbox.org/git/656C30A1EFC89F6B2082D9B6@localhost/raw --- diff --git a/lib/PublicInbox/MID.pm b/lib/PublicInbox/MID.pm index c82e8401..cd56f272 100644 --- a/lib/PublicInbox/MID.pm +++ b/lib/PublicInbox/MID.pm @@ -87,6 +87,7 @@ sub uniq_mids ($) { my @ret; my %seen; foreach my $mid (@$mids) { + $mid =~ tr/\n\t\r//d; if (length($mid) > MAX_MID_SIZE) { warn "Message-ID: <$mid> too long, truncating\n"; $mid = substr($mid, 0, MAX_MID_SIZE); diff --git a/lib/PublicInbox/SearchMsg.pm b/lib/PublicInbox/SearchMsg.pm index ab971e00..c7787ea1 100644 --- a/lib/PublicInbox/SearchMsg.pm +++ b/lib/PublicInbox/SearchMsg.pm @@ -100,7 +100,7 @@ sub __hdr ($$) { my $mime = $self->{mime} or return; $val = $mime->header($field); $val = '' unless defined $val; - $val =~ tr/\n/ /; + $val =~ tr/\t\n/ /; $val =~ tr/\r//d; $self->{$field} = $val; } diff --git a/t/mid.t b/t/mid.t index 223be798..8c307c82 100644 --- a/t/mid.t +++ b/t/mid.t @@ -25,6 +25,17 @@ is(mid_escape('foo%!@(bar)'), 'foo%25!@(bar)'); $mime->header_set('In-Reply-To', ''); is_deeply(['hello', 'world', 'weld'], references($mime->header_obj), 'references combines with In-Reply-To'); + + $mime->header_set('References', "\n\t"); + $mime->header_set('In-Reply-To'); + is_deeply(references($mime->header_obj), ['hello', 'world'], + 'multiline References OK'); + $mime->header_set('References', ""); + is_deeply(references($mime->header_obj), ['helloworld'], + 'drop \t in References <656C30A1EFC89F6B2082D9B6@localhost>'); + $mime->header_set('Message-ID', ""); + is_deeply(mids($mime->header_obj), ['helloworld'], + 'drop \t in Message-ID'); } done_testing(); diff --git a/t/nntpd.t b/t/nntpd.t index 3698f98b..960e83c1 100644 --- a/t/nntpd.t +++ b/t/nntpd.t @@ -80,9 +80,10 @@ From: =?utf-8?Q?El=C3=A9anor?= Cc: $addr Message-Id: Content-Type: text/plain; charset=utf-8 -Subject: Testing for =?utf-8?Q?El=C3=A9anor?= +Subject: Testing for =?utf-8?Q?El=C3=A9anor?= Date: Thu, 01 Jan 1970 06:06:06 +0000 Content-Transfer-Encoding: 8bit +References: This is a test message for El\xc3\xa9anor EOF @@ -139,7 +140,8 @@ EOF 'from' => "El\xc3\xa9anor ", 'to' => "El\xc3\xa9anor ", 'cc' => $addr, - 'xref' => "example.com $group:1" + 'xref' => "example.com $group:1", + 'references' => '', ); my $s = IO::Socket::INET->new(%opts); @@ -189,7 +191,7 @@ EOF "El\xc3\xa9anor ", 'Thu, 01 Jan 1970 06:06:06 +0000', '', - '', + '', $len, '1' ] }, "XOVER range works"); @@ -198,7 +200,7 @@ EOF "El\xc3\xa9anor ", 'Thu, 01 Jan 1970 06:06:06 +0000', '', - '', + '', $len, '1' ] }, "XOVER by article works"); @@ -220,14 +222,15 @@ EOF is($r[1], "0\tTesting for El\xc3\xa9anor\t" . "El\xc3\xa9anor \t" . "Thu, 01 Jan 1970 06:06:06 +0000\t" . - "$mid\t\t$len\t1", 'OVER by Message-ID works'); + "$mid\t\t$len\t1", + 'OVER by Message-ID works'); is($r[2], '.', 'correctly terminated response'); } is_deeply($n->xhdr(qw(Cc 1-)), { 1 => 'test-nntpd@example.com' }, 'XHDR Cc 1- works'); - is_deeply($n->xhdr(qw(References 1-)), { 1 => '' }, - 'XHDR References 1- works (empty string)'); + is_deeply($n->xhdr(qw(References 1-)), { 1 => '' }, + 'XHDR References 1- works)'); is_deeply($n->xhdr(qw(list-id 1-)), {}, 'XHDR on invalid header returns empty');