]> Sergey Matveev's repositories - public-inbox.git/commitdiff
disallow "\t" and "\n" in OVER headers
authorEric Wong <e@80x24.org>
Fri, 20 Apr 2018 03:27:37 +0000 (03:27 +0000)
committerEric Wong <e@80x24.org>
Fri, 20 Apr 2018 03:27:53 +0000 (03:27 +0000)
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

lib/PublicInbox/MID.pm
lib/PublicInbox/SearchMsg.pm
t/mid.t
t/nntpd.t

index c82e84013ec0d68730423ab4b691074c5b690dc5..cd56f272613dc28551409593545eec5a2e80eb0e 100644 (file)
@@ -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);
index ab971e002d8a52846eaed9e83dacbab474e4f2d2..c7787ea1003db61221c6c2aa0d84ab41f60fd59d 100644 (file)
@@ -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 223be798c47704f7a1823e6f59037ead36c840c6..8c307c825d22a7e2747c8f35fb1df0909c798dcb 100644 (file)
--- 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', '<weld>');
        is_deeply(['hello', 'world', 'weld'], references($mime->header_obj),
                'references combines with In-Reply-To');
+
+       $mime->header_set('References', "<hello>\n\t<world>");
+       $mime->header_set('In-Reply-To');
+       is_deeply(references($mime->header_obj), ['hello', 'world'],
+               'multiline References OK');
+       $mime->header_set('References', "<hello\tworld>");
+       is_deeply(references($mime->header_obj), ['helloworld'],
+               'drop \t in References <656C30A1EFC89F6B2082D9B6@localhost>');
+       $mime->header_set('Message-ID', "<hello\tworld>");
+       is_deeply(mids($mime->header_obj), ['helloworld'],
+               'drop \t in Message-ID');
 }
 
 done_testing();
index 3698f98baccc5d4f119d1dddda274700c75f494e..960e83c182868c4c74e5f08643fd62f394395606 100644 (file)
--- a/t/nntpd.t
+++ b/t/nntpd.t
@@ -80,9 +80,10 @@ From: =?utf-8?Q?El=C3=A9anor?= <me\@example.com>
 Cc: $addr
 Message-Id: <nntp\@example.com>
 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: <ref       tab     squeezed>
 
 This is a test message for El\xc3\xa9anor
 EOF
@@ -139,7 +140,8 @@ EOF
                'from' => "El\xc3\xa9anor <me\@example.com>",
                'to' => "El\xc3\xa9anor <you\@example.com>",
                'cc' => $addr,
-               'xref' => "example.com $group:1"
+               'xref' => "example.com $group:1",
+               'references' => '<reftabsqueezed>',
        );
 
        my $s = IO::Socket::INET->new(%opts);
@@ -189,7 +191,7 @@ EOF
                        "El\xc3\xa9anor <me\@example.com>",
                        'Thu, 01 Jan 1970 06:06:06 +0000',
                        '<nntp@example.com>',
-                       '',
+                       '<reftabsqueezed>',
                        $len,
                        '1' ] }, "XOVER range works");
 
@@ -198,7 +200,7 @@ EOF
                        "El\xc3\xa9anor <me\@example.com>",
                        'Thu, 01 Jan 1970 06:06:06 +0000',
                        '<nntp@example.com>',
-                       '',
+                       '<reftabsqueezed>',
                        $len,
                        '1' ] }, "XOVER by article works");
 
@@ -220,14 +222,15 @@ EOF
                is($r[1], "0\tTesting for El\xc3\xa9anor\t" .
                        "El\xc3\xa9anor <me\@example.com>\t" .
                        "Thu, 01 Jan 1970 06:06:06 +0000\t" .
-                       "$mid\t\t$len\t1", 'OVER by Message-ID works');
+                       "$mid\t<reftabsqueezed>\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 => '<reftabsqueezed>' },
+                'XHDR References 1- works)');
        is_deeply($n->xhdr(qw(list-id 1-)), {},
                 'XHDR on invalid header returns empty');