diff options
author | Eric Wong <e@80x24.org> | 2016-08-14 10:21:09 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-08-14 10:51:02 +0000 |
commit | 9d1e5fadd7d18f4c96ab0509d673040e34225a04 (patch) | |
tree | dd89df05390a2ca2e06448ec0acdbf741729d36e /lib/PublicInbox | |
parent | 1d0ce406b75fc174bee51e77efe5f10c61fb6098 (diff) | |
download | public-inbox-9d1e5fadd7d18f4c96ab0509d673040e34225a04.tar.gz |
Based on reading RFC 3986, it seems '@', ':', '!', '$', '&', "'", '; '(', ')', '*', '+', ',', ';', '=' are all allowed in path-absolute where we have the Message-ID. In any case, it seems '@' is fairly common in path components nowadays and too common in Message-IDs.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r-- | lib/PublicInbox/ExtMsg.pm | 6 | ||||
-rw-r--r-- | lib/PublicInbox/Feed.pm | 4 | ||||
-rw-r--r-- | lib/PublicInbox/Hval.pm | 6 | ||||
-rw-r--r-- | lib/PublicInbox/MID.pm | 7 | ||||
-rw-r--r-- | lib/PublicInbox/Mbox.pm | 5 | ||||
-rw-r--r-- | lib/PublicInbox/NNTP.pm | 4 | ||||
-rw-r--r-- | lib/PublicInbox/NewsWWW.pm | 4 | ||||
-rw-r--r-- | lib/PublicInbox/SearchView.pm | 7 | ||||
-rw-r--r-- | lib/PublicInbox/View.pm | 31 | ||||
-rw-r--r-- | lib/PublicInbox/WWW.pm | 5 |
10 files changed, 41 insertions, 38 deletions
diff --git a/lib/PublicInbox/ExtMsg.pm b/lib/PublicInbox/ExtMsg.pm index 39ee05f4..67ce0407 100644 --- a/lib/PublicInbox/ExtMsg.pm +++ b/lib/PublicInbox/ExtMsg.pm @@ -105,7 +105,7 @@ again: my $code = 404; my $h = PublicInbox::Hval->new_msgid($mid); - my $href = $h->as_href; + my $href = $h->{href}; my $html = $h->as_html; my $title = "<$html> not found"; my $s = "<pre>Message-ID <$html>\nnot found\n"; @@ -120,7 +120,7 @@ again: my $u = $ibx->base_url($env) or next; foreach my $m (@$res) { my $p = PublicInbox::Hval->new_msgid($m); - my $r = $p->as_href; + my $r = $p->{href}; my $t = $p->as_html; $s .= qq{<a\nhref="$u$r/">$u$t/</a>\n}; } @@ -158,7 +158,7 @@ sub ext_urls { sub exact { my ($ctx, $found, $mid) = @_; my $h = PublicInbox::Hval->new_msgid($mid); - my $href = $h->as_href; + my $href = $h->{href}; my $html = $h->as_html; my $title = "<$html> found in "; my $end = @$found == 1 ? 'another inbox' : 'other inboxes'; diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm index 240c336f..232a91c0 100644 --- a/lib/PublicInbox/Feed.pm +++ b/lib/PublicInbox/Feed.pm @@ -137,7 +137,7 @@ sub emit_atom_thread { my $fh = $cb->([200, ['Content-Type' => 'application/atom+xml']]); my $ibx = $ctx->{-inbox}; my $html_url = $ibx->base_url($ctx->{env}); - $html_url .= PublicInbox::Hval->new_msgid($mid)->as_href; + $html_url .= PublicInbox::Hval->new_msgid($mid)->{href}; $feed_opts->{url} = $html_url; $feed_opts->{emit_header} = 1; @@ -269,7 +269,7 @@ sub feed_entry { my $mid = $header_obj->header_raw('Message-ID'); defined $mid or return; $mid = PublicInbox::Hval->new_msgid($mid); - my $href = $midurl . $mid->as_href . '/'; + my $href = $midurl . $mid->{href}. '/'; my $date = $header_obj->header('Date'); my $updated = feed_updated($date); diff --git a/lib/PublicInbox/Hval.pm b/lib/PublicInbox/Hval.pm index f2620737..72496065 100644 --- a/lib/PublicInbox/Hval.pm +++ b/lib/PublicInbox/Hval.pm @@ -7,8 +7,7 @@ package PublicInbox::Hval; use strict; use warnings; use Encode qw(find_encoding); -use URI::Escape qw(uri_escape_utf8); -use PublicInbox::MID qw/mid_clean/; +use PublicInbox::MID qw/mid_clean mid_escape/; use base qw/Exporter/; our @EXPORT_OK = qw/ascii_html/; @@ -33,7 +32,7 @@ sub new { sub new_msgid { my ($class, $msgid) = @_; $msgid = mid_clean($msgid); - $class->new($msgid, $msgid); + $class->new($msgid, mid_escape($msgid)); } sub new_oneline { @@ -74,7 +73,6 @@ sub ascii_html { } sub as_html { ascii_html($_[0]->{raw}) } -sub as_href { ascii_html(uri_escape_utf8($_[0]->{href})) } sub raw { if (defined $_[1]) { diff --git a/lib/PublicInbox/MID.pm b/lib/PublicInbox/MID.pm index bb40cc76..1c2d75cc 100644 --- a/lib/PublicInbox/MID.pm +++ b/lib/PublicInbox/MID.pm @@ -6,7 +6,8 @@ package PublicInbox::MID; use strict; use warnings; use base qw/Exporter/; -our @EXPORT_OK = qw/mid_clean id_compress mid2path mid_mime/; +our @EXPORT_OK = qw/mid_clean id_compress mid2path mid_mime mid_escape/; +use URI::Escape qw(uri_escape_utf8); use Digest::SHA qw/sha1_hex/; use constant MID_MAX => 40; # SHA-1 hex length @@ -47,4 +48,8 @@ sub mid2path { sub mid_mime ($) { $_[0]->header_obj->header_raw('Message-ID') } +# RFC3986, section 3.3: +sub MID_ESC () { '^A-Za-z0-9\-\._~!\$\&\';\(\)\*\+,;=:@' } +sub mid_escape ($) { uri_escape_utf8($_[0], MID_ESC) } + 1; diff --git a/lib/PublicInbox/Mbox.pm b/lib/PublicInbox/Mbox.pm index dc41548b..fd623f6d 100644 --- a/lib/PublicInbox/Mbox.pm +++ b/lib/PublicInbox/Mbox.pm @@ -6,8 +6,7 @@ package PublicInbox::Mbox; use strict; use warnings; -use PublicInbox::MID qw/mid_clean/; -use URI::Escape qw/uri_escape_utf8/; +use PublicInbox::MID qw/mid_clean mid_escape/; require Email::Simple; sub emit1 { @@ -29,7 +28,7 @@ sub msg_str { my $ibx = $ctx->{-inbox}; my $base = $ibx->base_url($ctx->{env}); my $mid = mid_clean($header_obj->header('Message-ID')); - $mid = uri_escape_utf8($mid); + $mid = mid_escape($mid); my @append = ( 'Archived-At', "<$base$mid/>", 'List-Archive', "<$base>", diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 0c61dd8a..7bfc6dd6 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -9,12 +9,12 @@ use base qw(Danga::Socket); use fields qw(nntpd article rbuf ng long_res); use PublicInbox::Search; use PublicInbox::Msgmap; +use PublicInbox::MID qw(mid_escape); use PublicInbox::Git; require PublicInbox::EvCleanup; use Email::Simple; use POSIX qw(strftime); use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC); -use URI::Escape qw(uri_escape_utf8); use constant { r501 => '501 command syntax error', r221 => '221 Header follows', @@ -421,7 +421,7 @@ sub set_nntp_headers { $hdr->header_set('Xref', xref($ng, $n)); header_append($hdr, 'List-Post', "<mailto:$ng->{-primary_address}>"); if (my $url = $ng->base_url) { - $mid = uri_escape_utf8($mid); + $mid = mid_escape($mid); header_append($hdr, 'Archived-At', "<$url$mid/>"); header_append($hdr, 'List-Archive', "<$url>"); } diff --git a/lib/PublicInbox/NewsWWW.pm b/lib/PublicInbox/NewsWWW.pm index 9b01dcd3..b4d74763 100644 --- a/lib/PublicInbox/NewsWWW.pm +++ b/lib/PublicInbox/NewsWWW.pm @@ -9,7 +9,7 @@ package PublicInbox::NewsWWW; use strict; use warnings; use PublicInbox::Config; -use URI::Escape qw(uri_escape_utf8); +use PublicInbox::MID qw(mid_escape); sub new { my ($class, $pi_config) = @_; @@ -35,7 +35,7 @@ sub call { # article IDs are not stable across clones, # do not encourage caching/bookmarking them $code = 302; - $url .= uri_escape_utf8($mid) . '/'; + $url .= mid_escape($mid) . '/'; } } diff --git a/lib/PublicInbox/SearchView.pm b/lib/PublicInbox/SearchView.pm index 80a2ff7c..3623a78b 100644 --- a/lib/PublicInbox/SearchView.pm +++ b/lib/PublicInbox/SearchView.pm @@ -8,7 +8,7 @@ use warnings; use PublicInbox::SearchMsg; use PublicInbox::Hval qw/ascii_html/; use PublicInbox::View; -use PublicInbox::MID qw(mid2path mid_mime mid_clean); +use PublicInbox::MID qw(mid2path mid_mime mid_clean mid_escape); use Email::MIME; require PublicInbox::Git; require PublicInbox::Thread; @@ -74,7 +74,7 @@ sub mset_summary { my $s = ascii_html($smsg->subject); my $f = ascii_html($smsg->from_name); my $ts = PublicInbox::View::fmt_ts($smsg->ts); - my $mid = PublicInbox::Hval->new_msgid($smsg->mid)->as_href; + my $mid = PublicInbox::Hval->new_msgid($smsg->mid)->{href}; $$res .= qq{$rank. <b><a\nhref="$mid/">}. $s . "</a></b>\n"; $$res .= "$pfx - by $f @ $ts UTC [$pct%]\n\n"; @@ -239,6 +239,7 @@ package PublicInbox::SearchQuery; use strict; use warnings; use PublicInbox::Hval; +use PublicInbox::MID qw(mid_escape); sub new { my ($class, $qp) = @_; @@ -263,7 +264,7 @@ sub qs_html { $self = $tmp; } - my $q = PublicInbox::Hval->new($self->{'q'})->as_href; + my $q = mid_escape($self->{'q'}); $q =~ s/%20/+/g; # improve URL readability my $qs = "q=$q"; diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index 3982a47f..34f97c76 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -10,7 +10,7 @@ use URI::Escape qw/uri_escape_utf8/; use Date::Parse qw/str2time/; use PublicInbox::Hval qw/ascii_html/; use PublicInbox::Linkify; -use PublicInbox::MID qw/mid_clean id_compress mid_mime/; +use PublicInbox::MID qw/mid_clean id_compress mid_mime mid_escape/; use PublicInbox::MsgIter; use PublicInbox::Address; use PublicInbox::WwwStream; @@ -125,7 +125,6 @@ sub index_entry { my $mid_raw = mid_clean(mid_mime($mime)); my $id = id_compress($mid_raw, 1); my $id_m = 'm'.$id; - my $mid = PublicInbox::Hval->new_msgid($mid_raw); my $root_anchor = $ctx->{root_anchor} || ''; my $irt = in_reply_to($hdr); @@ -142,7 +141,7 @@ sub index_entry { } $rv .= "From: "._hdr_names($hdr, 'From').' @ '._msg_date($hdr)." UTC"; my $upfx = $ctx->{-upfx}; - my $mhref = $upfx . $mid->as_href . '/'; + my $mhref = $upfx . mid_escape($mid_raw) . '/'; $rv .= qq{ (<a\nhref="$mhref">permalink</a> / }; $rv .= qq{<a\nhref="${mhref}raw">raw</a>)\n}; $rv .= ' '.join('; +', @tocc) . "\n" if @tocc; @@ -150,7 +149,7 @@ sub index_entry { my $mapping = $ctx->{mapping}; if (!$mapping && $irt) { my $mirt = PublicInbox::Hval->new_msgid($irt); - my $href = $upfx . $mirt->as_href . '/'; + my $href = $upfx . $mirt->{href}. '/'; my $html = $mirt->as_html; $rv .= qq(In-Reply-To: <<a\nhref="$href">$html</a>>\n) } @@ -568,7 +567,7 @@ sub _parent_headers { if (defined $irt) { my $v = PublicInbox::Hval->new_msgid($irt); my $html = $v->as_html; - my $href = $v->as_href; + my $href = $v->{href}; $rv .= "In-Reply-To: <"; $rv .= "<a\nhref=\"../$href/\">$html</a>>\n"; } @@ -627,7 +626,7 @@ sub mailto_arg_link { $subj = "Re: $subj" unless $subj =~ /\bRe:/i; my $mid = $hdr->header_raw('Message-ID'); push @arg, '--in-reply-to='.squote_maybe(mid_clean($mid)); - my $irt = uri_escape_utf8($mid); + my $irt = mid_escape($mid); delete $cc{$to}; push @arg, "--to=$to"; $to = uri_escape_utf8($to); @@ -657,17 +656,17 @@ sub html_footer { $next = $prev = ' '; if (my $n = $ctx->{next_msg}) { - $n = PublicInbox::Hval->new_msgid($n)->as_href; + $n = PublicInbox::Hval->new_msgid($n)->{href}; $next = "<a\nhref=\"$upfx$n/\"\nrel=next>next</a>"; } my $u; my $par = $ctx->{parent_msg}; if ($par) { - $u = PublicInbox::Hval->new_msgid($par)->as_href; + $u = PublicInbox::Hval->new_msgid($par)->{href}; $u = "$upfx$u/"; } if (my $p = $ctx->{prev_msg}) { - $prev = PublicInbox::Hval->new_msgid($p)->as_href; + $prev = PublicInbox::Hval->new_msgid($p)->{href}; if ($p && $par && $p eq $par) { $prev = "<a\nhref=\"$upfx$prev/\"\n" . 'rel=prev>prev parent</a>'; @@ -692,7 +691,7 @@ sub html_footer { sub linkify_ref_nosrch { my $v = PublicInbox::Hval->new_msgid($_[0]); my $html = $v->as_html; - my $href = $v->as_href; + my $href = $v->{href}; "<<a\nhref=\"../$href/\">$html</a>>"; } @@ -707,7 +706,7 @@ sub ghost_parent { return '[no common parent]' if ($mid eq 'subject dummy'); $mid = PublicInbox::Hval->new_msgid($mid); - my $href = $mid->as_href; + my $href = $mid->{href}; my $html = $mid->as_html; qq{[parent not found: <<a\nhref="$upfx$href/">$html</a>>]}; } @@ -793,7 +792,7 @@ sub _skel_header { $s = PublicInbox::Hval->new($s); $s = $s->as_html; } - my $m = PublicInbox::Hval->new_msgid($mid); + my $m; my $id = ''; my $mapping = $ctx->{mapping}; my $end = defined($s) ? "$s</a> $f\n" : "$f</a>\n"; @@ -804,7 +803,7 @@ sub _skel_header { $map->[1] = "$d<a\nhref=\"$m\">$end"; $id = "\nid=r".$id; } else { - $m = $ctx->{-upfx}.$m->as_href.'/'; + $m = $ctx->{-upfx}.mid_escape($mid).'/'; } $$dst .= $d . "<a\nhref=\"$m\"$id>" . $end; } @@ -829,7 +828,7 @@ sub skel_dump { $d .= indent_for($level) . th_pfx($level); my $upfx = $ctx->{-upfx}; my $m = PublicInbox::Hval->new_msgid($mid); - my $href = $upfx . $m->as_href . '/'; + my $href = $upfx . $m->{href} . '/'; my $html = $m->as_html; if ($map) { @@ -911,7 +910,7 @@ sub dump_topics { @$topic = (); next unless defined $top; # ghost topic my $mid = delete $seen->{$top}; - my $href = PublicInbox::Hval->new_msgid($mid)->as_href; + my $href = mid_escape($mid); $top = PublicInbox::Hval->new($top)->as_html; $ts = fmt_ts($ts); @@ -935,7 +934,7 @@ sub dump_topics { my $sub = $ex[$i + 1]; $mid = delete $seen->{$sub}; $sub = PublicInbox::Hval->new($sub)->as_html; - $href = PublicInbox::Hval->new_msgid($mid)->as_href; + $href = mid_escape($mid); $s .= indent_for($level) . TCHILD; $s .= "<a\nhref=\"$href/T/#u\">$sub</a>\n"; } diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 60cb4430..6f6a0033 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -15,7 +15,8 @@ use strict; use warnings; use PublicInbox::Config; use PublicInbox::Hval; -use URI::Escape qw(uri_escape_utf8 uri_unescape); +use URI::Escape qw(uri_unescape); +use PublicInbox::MID qw(mid_escape); require PublicInbox::Git; use PublicInbox::GitHTTPBackend; our $INBOX_RE = qr!\A/([\w\.\-]+)!; @@ -353,7 +354,7 @@ sub r301 { } my $url = $obj->base_url($ctx->{env}); my $qs = $ctx->{env}->{QUERY_STRING}; - $url .= (uri_escape_utf8($mid) . '/') if (defined $mid); + $url .= (mid_escape($mid) . '/') if (defined $mid); $url .= $suffix if (defined $suffix); $url .= "?$qs" if $qs ne ''; |