about summary refs log tree commit homepage
path: root/lib/PublicInbox/Config.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2020-12-21 07:51:20 +0000
committerEric Wong <e@80x24.org>2020-12-21 21:51:57 +0000
commit3e9888ed30b7fe092b03789d19a8020d4bc0fb39 (patch)
treefcdb2a81886f3526ddaa09c674eea308310bef6b /lib/PublicInbox/Config.pm
parentbad84119fb0915abe3f19fe4fb9c34e24fe7e564 (diff)
downloadpublic-inbox-3e9888ed30b7fe092b03789d19a8020d4bc0fb39.tar.gz
We need to canonicalize paths for inboxes which do not have
a newsgroup defined, otherwise ->eidx_key matches can fail
in unexpected ways.
Diffstat (limited to 'lib/PublicInbox/Config.pm')
-rw-r--r--lib/PublicInbox/Config.pm28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index 2f5c83cd..577337dc 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -368,6 +368,16 @@ sub git_bool {
         }
 }
 
+# abs_path resolves symlinks, so we want to avoid it if rel2abs
+# is sufficient and doesn't leave "/.." or "/../"
+sub rel2abs_collapsed {
+        require File::Spec;
+        my $p = File::Spec->rel2abs($_[-1]);
+        return $p if substr($p, -3, 3) ne '/..' && index($p, '/../') < 0;
+        require Cwd;
+        Cwd::abs_path($p);
+}
+
 sub _fill {
         my ($self, $pfx) = @_;
         my $ibx = {};
@@ -391,9 +401,9 @@ EOF
         }
 
         # "mainrepo" is backwards compatibility:
-        $ibx->{inboxdir} //= $self->{"$pfx.mainrepo"} // return;
-        if ($ibx->{inboxdir} =~ /\n/s) {
-                warn "E: `$ibx->{inboxdir}' must not contain `\\n'\n";
+        my $dir = $ibx->{inboxdir} //= $self->{"$pfx.mainrepo"} // return;
+        if (index($dir, "\n") >= 0) {
+                warn "E: `$dir' must not contain `\\n'\n";
                 return;
         }
         foreach my $k (qw(obfuscate)) {
@@ -436,7 +446,7 @@ EOF
                         $self->{-by_list_id}->{lc($list_id)} = $ibx;
                 }
         }
-        if (my $ngname = $ibx->{newsgroup}) {
+        if (defined(my $ngname = $ibx->{newsgroup})) {
                 if (ref($ngname)) {
                         delete $ibx->{newsgroup};
                         warn 'multiple newsgroups not supported: '.
@@ -445,7 +455,8 @@ EOF
                 # wildmat-exact and RFC 3501 (IMAP) ATOM-CHAR.
                 # Leave out a few chars likely to cause problems or conflicts:
                 # '|', '<', '>', ';', '#', '$', '&',
-                } elsif ($ngname =~ m![^A-Za-z0-9/_\.\-\~\@\+\=:]!) {
+                } elsif ($ngname =~ m![^A-Za-z0-9/_\.\-\~\@\+\=:]! ||
+                                $ngname eq '') {
                         delete $ibx->{newsgroup};
                         warn "newsgroup name invalid: `$ngname'\n";
                 } else {
@@ -454,6 +465,13 @@ EOF
                         $self->{-by_newsgroup}->{$ngname} = $ibx;
                 }
         }
+        unless (defined $ibx->{newsgroup}) { # for ->eidx_key
+                my $abs = rel2abs_collapsed($dir);
+                if ($abs ne $dir) {
+                        warn "W: `$dir' canonicalized to `$abs'\n";
+                        $ibx->{inboxdir} = $abs;
+                }
+        }
         $self->{-by_name}->{$name} = $ibx;
         if ($ibx->{obfuscate}) {
                 $ibx->{-no_obfuscate} = $self->{-no_obfuscate};