X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiExternal.pm;h=b0ebe9479b6254294fada399d746933484a7d6e2;hb=2018db2a23ab1d949c757c264534f39dba338ccb;hp=0cc84ccaec3b6b4823a5cbd260c6687823968b04;hpb=16396c1c2f4968d465ef99a68b3d76d7c1f32628;p=public-inbox.git diff --git a/lib/PublicInbox/LeiExternal.pm b/lib/PublicInbox/LeiExternal.pm index 0cc84cca..b0ebe947 100644 --- a/lib/PublicInbox/LeiExternal.pm +++ b/lib/PublicInbox/LeiExternal.pm @@ -54,6 +54,12 @@ sub glob2re { my $p = ''; my $in_bracket = 0; my $qm = 0; + my $schema_host_port = ''; + + # don't glob URL-looking things that look like IPv6 + if ($re =~ s!\A([a-z0-9\+]+://\[[a-f0-9\:]+\](?::[0-9]+)?/)!!i) { + $schema_host_port = quotemeta $1; # "http://[::1]:1234" + } my $changes = ($re =~ s!(.)! $re_map{$p eq '\\' ? '' : do { if ($1 eq '[') { ++$in_bracket } @@ -69,7 +75,7 @@ sub glob2re { (my $in_braces = $2) =~ tr!,!|!; $1."($in_braces)"; /sge); - ($changes - $qm) ? $re : undef; + ($changes - $qm) ? $schema_host_port.$re : undef; } # get canonicalized externals list matching $loc @@ -138,12 +144,11 @@ sub add_external_finish { sub lei_add_external { my ($self, $location) = @_; - $self->_lei_store(1)->write_prepare($self); my $opt = $self->{opt}; my $mirror = $opt->{mirror} // do { my @fail; for my $sw ($self->index_opt, $self->curl_opt, - qw(c no-torsocks torsocks inbox-version)) { + qw(no-torsocks torsocks inbox-version)) { my ($f) = (split(/|/, $sw, 2))[0]; next unless defined $opt->{$f}; $f = length($f) == 1 ? "-$f" : "--$f"; @@ -164,9 +169,14 @@ sub lei_add_external { $self->fail(<<""); # TODO: did you mean "update-external?" --mirror destination `$location' already exists + } elsif (-d $location) { + index($location, "\n") >= 0 and + return $self->fail("`\\n' not allowed in `$location'"); } if ($location !~ m!\Ahttps?://! && !-d $location) { $mirror // return $self->fail("$location not a directory"); + index($location, "\n") >= 0 and + return $self->fail("`\\n' not allowed in `$location'"); $mirror = ext_canonicalize($mirror); require PublicInbox::LeiMirror; PublicInbox::LeiMirror->start($self, $mirror => $location); @@ -205,20 +215,21 @@ sub lei_forget_external { } } -sub _complete_url_common ($) { - my ($argv) = @_; +sub complete_url_common { + my $argv = $_[-1]; # Workaround bash word-splitting URLs to ['https', ':', '//' ...] # Maybe there's a better way to go about this in # contrib/completion/lei-completion.bash my $re = ''; - my $cur = pop @$argv; + my $cur = pop(@$argv) // ''; if (@$argv) { my @x = @$argv; if ($cur eq ':' && @x) { push @x, $cur; $cur = ''; } - while (@x > 2 && $x[0] !~ /\Ahttps?\z/ && $x[1] ne ':') { + while (@x > 2 && $x[0] !~ /\A(?:http|nntp|imap)s?\z/i && + $x[1] ne ':') { shift @x; } if (@x >= 2) { # qw(https : hostname : 443) or qw(http :) @@ -235,7 +246,7 @@ sub _complete_url_common ($) { sub _complete_forget_external { my ($self, @argv) = @_; my $cfg = $self->_lei_cfg; - my ($cur, $re) = _complete_url_common(\@argv); + my ($cur, $re) = complete_url_common(\@argv); # FIXME: bash completion off "http:" or "https:" when the last # character is a colon doesn't work properly even if we're # returning "//$HTTP_HOST/$PATH_INFO/", not sure why, could @@ -251,7 +262,7 @@ sub _complete_forget_external { sub _complete_add_external { # for bash, this relies on "compopt -o nospace" my ($self, @argv) = @_; my $cfg = $self->_lei_cfg; - my ($cur, $re) = _complete_url_common(\@argv); + my ($cur, $re) = complete_url_common(\@argv); require URI; map { my $u = URI->new(substr($_, length('external.')));