]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
www: strip and redirect on `<' and `>' in MSGID of URL
authorEric Wong <e@80x24.org>
Mon, 17 Jun 2024 00:01:40 +0000 (00:01 +0000)
committerEric Wong <e@80x24.org>
Mon, 17 Jun 2024 07:25:28 +0000 (07:25 +0000)
Some users may needlessly include `<' and `>' braces in URLs, so
account for this common mistake and redirect users to the
non-braced URL.  This common mistake could be learned behavior
from other sites (e.g. sr.ht) which include `<' and `>' in URLs.

Reported-by: Junio C Hamano <gitster@pobox.com>
Link: https://public-inbox.org/meta/xmqqtthvh4r6.fsf@gitster.g/
lib/PublicInbox/View.pm
t/psgi_search.t

index dcceb3112ba3af15d376641fa8047cc51738d530..cc1ab79a94472daa63dd8a603e7ef38c6913112a 100644 (file)
@@ -74,9 +74,13 @@ sub msg_page {
        my ($id, $prev);
        my $next_arg = $ctx->{next_arg} = [ $ctx->{mid}, \$id, \$prev ];
 
-       my $smsg = $ctx->{smsg} = $over->next_by_mid(@$next_arg) or
-               return; # undef == 404
-
+       my $smsg = $ctx->{smsg} = $over->next_by_mid(@$next_arg);
+       if (!$smsg && $ctx->{mid} =~ /\A\<(.+)\>\z/ and
+                       ($next_arg->[0] = $1) and
+                       ($over->next_by_mid(@$next_arg))) {
+               return PublicInbox::WWW::r301($ctx, undef, $next_arg->[0]);
+       }
+       $smsg or return; # undef=404
        # allow user to easily browse the range around this message if
        # they have ->over
        $ctx->{-t_max} = $smsg->{ts};
index 8c981c6cc593e78252335ac2c9bfdfcfbd4e1e03..759dab781c9b6ba75c5f1065586652de1649a47e 100644 (file)
@@ -179,6 +179,17 @@ test_psgi(sub { $www->call(@_) }, sub {
 
        $res = $cb->(GET(q{/test/?q=%22s'more%22&x=A}));
        is $res->code, 200, 'single quote inside phrase';
+
+       $res = $cb->(GET("/test/<$mid>/"));
+       is $res->code, 301, "redirect for raw `<' and `>' in msgid";
+       like $res->header('location'), qr!/test/\Q$mid\E/\z!,
+               "redirected to URL without raw `<' and `>'";
+
+       $res = $cb->(GET("/test/%3c$mid%3e/"));
+       is $res->code, 301, "redirect for escaped `<' and `>' in msgid";
+       like $res->header('location'), qr!/test/\Q$mid\E/\z!,
+               "redirected to URL without escaped `<' and `>'";
+
        # TODO: more tests and odd cases
 });