unofficial mirror of meta@public-inbox.org
 help / color / mirror / Atom feed
* [PATCH 0/4] www: PSGI test fixes + URL-fication tests
@ 2024-09-16 21:02 Eric Wong
  2024-09-16 21:02 ` [PATCH 1/4] config: ignore blank address= and listid= entries Eric Wong
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Eric Wong @ 2024-09-16 21:02 UTC (permalink / raw)
  To: meta

More followup for some stuff fixed in the past few weeks.

Eric Wong (4):
  config: ignore blank address= and listid= entries
  test_common: -httpd requires HTTP::{Date,Status}
  test_common: improve psgi test setup + loading
  www: test address URL-fication

 MANIFEST                      |  1 +
 lib/PublicInbox/Config.pm     | 10 ++---
 lib/PublicInbox/TestCommon.pm | 27 ++++++++++---
 lib/PublicInbox/View.pm       |  2 +-
 t/clone-coderepo.t            |  5 +--
 t/extindex-psgi.t             |  4 +-
 t/httpd-corner.t              |  6 +--
 t/httpd-https.t               |  2 +-
 t/httpd-unix.t                |  2 +-
 t/httpd.t                     |  4 +-
 t/plack.t                     |  4 +-
 t/psgi_attach.t               |  4 +-
 t/psgi_bad_mids.t             |  7 +---
 t/psgi_mount.t                |  5 +--
 t/psgi_multipart_not.t        |  5 +--
 t/psgi_scan_all.t             |  5 +--
 t/psgi_search.t               |  5 +--
 t/psgi_text.t                 |  3 +-
 t/psgi_urlfication.t          | 71 +++++++++++++++++++++++++++++++++++
 t/psgi_v2.t                   |  4 +-
 t/solver_git.t                |  6 +--
 t/v2mirror.t                  |  3 +-
 t/www_altid.t                 |  4 +-
 t/www_listing.t               |  2 +-
 t/www_static.t                |  4 +-
 25 files changed, 126 insertions(+), 69 deletions(-)
 create mode 100644 t/psgi_urlfication.t

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] config: ignore blank address= and listid= entries
  2024-09-16 21:02 [PATCH 0/4] www: PSGI test fixes + URL-fication tests Eric Wong
@ 2024-09-16 21:02 ` Eric Wong
  2024-09-16 21:02 ` [PATCH 2/4] test_common: -httpd requires HTTP::{Date,Status} Eric Wong
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2024-09-16 21:02 UTC (permalink / raw)
  To: meta

At the minimum, there must be a non-space character in
address= and listid= entries for matches to occur.
Filter out the obviously unmatchable entries here to
avoid potential problems elsewhere.
---
 lib/PublicInbox/Config.pm | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index cda3045e..d76deca4 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -492,16 +492,14 @@ sub _fill_ibx {
 	($ibx->{name}) = keys %dedupe; # used as a key everywhere
 	$ibx->{-pi_cfg} = $self;
 	$ibx = PublicInbox::Inbox->new($ibx);
-	foreach (@{$ibx->{address}}) {
+	for (grep /\S/, @{$ibx->{address}}) {
 		my $lc_addr = lc($_);
 		$self->{-by_addr}->{$lc_addr} = $ibx;
 		$self->{-no_obfuscate}->{$lc_addr} = 1;
 	}
-	if (my $listids = $ibx->{listid}) {
-		# RFC2919 section 6 stipulates "case insensitive equality"
-		foreach my $list_id (@$listids) {
-			$self->{-by_list_id}->{lc($list_id)} = $ibx;
-		}
+	# RFC2919 section 6 stipulates "case insensitive equality"
+	for my $list_id (grep /\S/, @{$ibx->{listid} // []}) {
+		$self->{-by_list_id}->{lc($list_id)} = $ibx;
 	}
 	if (defined(my $ngname = $ibx->{newsgroup})) {
 		if (ref($ngname)) {

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/4] test_common: -httpd requires HTTP::{Date,Status}
  2024-09-16 21:02 [PATCH 0/4] www: PSGI test fixes + URL-fication tests Eric Wong
  2024-09-16 21:02 ` [PATCH 1/4] config: ignore blank address= and listid= entries Eric Wong
@ 2024-09-16 21:02 ` Eric Wong
  2024-09-16 21:03 ` [PATCH 3/4] test_common: improve psgi test setup + loading Eric Wong
  2024-09-16 21:03 ` [PATCH 4/4] www: test address URL-fication Eric Wong
  3 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2024-09-16 21:02 UTC (permalink / raw)
  To: meta

HTTP::Date and HTTP::Status are required for Plack anyways,
but make it explicit in case we drop the Plack requirement.
---
 lib/PublicInbox/TestCommon.pm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 8c70c6c2..195dc3eb 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -209,7 +209,8 @@ sub require_mods {
 		if ($mod eq 'json') {
 			$mod = 'Cpanel::JSON::XS||JSON::MaybeXS||JSON||JSON::PP'
 		} elsif ($mod eq '-httpd') {
-			push @mods, qw(Plack::Builder Plack::Util);
+			push @mods, qw(Plack::Builder Plack::Util
+				HTTP::Date HTTP::Status);
 			next;
 		} elsif ($mod eq '-imapd') {
 			push @mods, qw(Parse::RecDescent DBD::SQLite);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/4] test_common: improve psgi test setup + loading
  2024-09-16 21:02 [PATCH 0/4] www: PSGI test fixes + URL-fication tests Eric Wong
  2024-09-16 21:02 ` [PATCH 1/4] config: ignore blank address= and listid= entries Eric Wong
  2024-09-16 21:02 ` [PATCH 2/4] test_common: -httpd requires HTTP::{Date,Status} Eric Wong
@ 2024-09-16 21:03 ` Eric Wong
  2024-09-16 21:03 ` [PATCH 4/4] www: test address URL-fication Eric Wong
  3 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2024-09-16 21:03 UTC (permalink / raw)
  To: meta

Since we have many PSGI tests nowadays, put in a `psgi' shortcut
like we do for many other components for `require_mods' to make
it easier to load a consistent set of modules.

We'll also cut down on `require_ok' and `use_ok' tests since
they should be limited to code maintained in our source tree,
not 3rd-party dependencies.
---
 lib/PublicInbox/TestCommon.pm | 24 +++++++++++++++++++-----
 t/clone-coderepo.t            |  5 ++---
 t/extindex-psgi.t             |  4 +---
 t/httpd-corner.t              |  6 ++----
 t/httpd-https.t               |  2 +-
 t/httpd-unix.t                |  2 +-
 t/httpd.t                     |  4 ++--
 t/plack.t                     |  4 +---
 t/psgi_attach.t               |  4 +---
 t/psgi_bad_mids.t             |  7 ++-----
 t/psgi_mount.t                |  5 +----
 t/psgi_multipart_not.t        |  5 +----
 t/psgi_scan_all.t             |  5 ++---
 t/psgi_search.t               |  5 +----
 t/psgi_text.t                 |  3 +--
 t/psgi_v2.t                   |  4 +---
 t/solver_git.t                |  6 ++----
 t/v2mirror.t                  |  3 +--
 t/www_altid.t                 |  4 ++--
 t/www_listing.t               |  2 +-
 t/www_static.t                |  4 ++--
 21 files changed, 47 insertions(+), 61 deletions(-)

diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 195dc3eb..913aa7e9 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -196,10 +196,11 @@ sub need_accept_filter ($) {
 		skip "$af not loaded: kldload $af", 1;
 }
 
-sub require_mods {
+sub require_mods (@) {
 	my @mods = @_;
 	my $maybe = pop @mods if $mods[-1] =~ /\A[0-9]+\z/;
-	my @need;
+	my (@need, @use);
+
 	while (my $mod = shift(@mods)) {
 		if ($mod eq 'lei') {
 			require_git(2.6, $maybe ? $maybe : ());
@@ -212,6 +213,12 @@ sub require_mods {
 			push @mods, qw(Plack::Builder Plack::Util
 				HTTP::Date HTTP::Status);
 			next;
+		} elsif ($mod eq 'psgi') {
+			my @m = qw(Plack::Test HTTP::Request::Common
+				Plack::Builder);
+			push @use, @m;
+			push @mods, qw(Plack::Util), @m;
+			next;
 		} elsif ($mod eq '-imapd') {
 			push @mods, qw(Parse::RecDescent DBD::SQLite);
 			next;
@@ -263,7 +270,14 @@ sub require_mods {
 			$ENV{TEST_IPV4_ONLY} = 1 if !eval { $mod->VERSION($v) };
 		}
 	}
-	return unless @need;
+	unless (@need) {
+		for my $mod (@use) {
+			my ($pkg) = caller(0);
+			eval "package $pkg; $mod->import";
+			xbail "$mod->import: $@" if $@;
+		}
+		return;
+	}
 	my $m = join(', ', @need)." missing for $0";
 	$m =~ s/\bEmail::MIME\b/Email::MIME (development purposes only)/;
 	skip($m, $maybe) if $maybe;
@@ -941,8 +955,8 @@ sub test_httpd ($$;$$) {
 	};
 	for (qw(PI_CONFIG)) { $env->{$_} or BAIL_OUT "$_ unset" }
 	SKIP: {
-		require_mods(qw(Plack::Test::ExternalServer LWP::UserAgent),
-				$skip // 1);
+		require_mods qw(Plack::Test::ExternalServer LWP::UserAgent
+				-httpd), $skip // 1;
 		my $sock = tcp_server() or die;
 		my ($out, $err) = map { "$env->{TMPDIR}/std$_.log" } qw(out err);
 		my $cmd = [ qw(-httpd -W0), "--stdout=$out", "--stderr=$err" ];
diff --git a/t/clone-coderepo.t b/t/clone-coderepo.t
index c6180fc4..8986351e 100644
--- a/t/clone-coderepo.t
+++ b/t/clone-coderepo.t
@@ -8,9 +8,9 @@ use File::Temp;
 use File::Path qw(remove_tree);
 use PublicInbox::SHA qw(sha1_hex);
 use PublicInbox::IO;
-require_mods(qw(json Plack::Builder HTTP::Date HTTP::Status));
+require_mods qw(json psgi -httpd);
 require_git_http_backend;
-require_git '1.8.5';
+require_git v1.8.5;
 require_cmd 'curl';
 require_ok 'PublicInbox::LeiMirror';
 my ($tmpdir, $for_destroy) = tmpdir();
@@ -201,7 +201,6 @@ ok(-e "$tmpdir/dst/objstore", 'objstore created');
 	xsys_e([qw(git clone -q), "${url}c.git", "$tmpdir/dst/c.git"]);
 	SKIP: {
 		require_mods(qw(Plack::Test::ExternalServer LWP::UserAgent), 1);
-		use_ok($_) for qw(HTTP::Request::Common);
 		chop(my $uri = $url) eq '/' or xbail "BUG: no /";
 		local $ENV{PLACK_TEST_EXTERNALSERVER_URI} = $uri;
 		my %opt = (ua => LWP::UserAgent->new);
diff --git a/t/extindex-psgi.t b/t/extindex-psgi.t
index 896c46ff..5fa0b99d 100644
--- a/t/extindex-psgi.t
+++ b/t/extindex-psgi.t
@@ -8,9 +8,7 @@ use PublicInbox::Config;
 use File::Copy qw(cp);
 use IO::Handle ();
 require_git(2.6);
-require_mods(qw(json DBD::SQLite Xapian
-		HTTP::Request::Common Plack::Test URI::Escape Plack::Builder));
-use_ok($_) for (qw(HTTP::Request::Common Plack::Test));
+require_mods qw(json DBD::SQLite Xapian psgi);
 use IO::Uncompress::Gunzip qw(gunzip);
 require PublicInbox::WWW;
 my ($ro_home, $cfg_path) = setup_public_inboxes;
diff --git a/t/httpd-corner.t b/t/httpd-corner.t
index 7539573c..125610d6 100644
--- a/t/httpd-corner.t
+++ b/t/httpd-corner.t
@@ -7,7 +7,7 @@ use v5.12; use PublicInbox::TestCommon;
 use Time::HiRes qw(gettimeofday tv_interval);
 use autodie qw(getsockopt setsockopt);
 use PublicInbox::Spawn qw(spawn popen_rd);
-require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
+require_mods '-httpd';
 use PublicInbox::SHA qw(sha1_hex);
 use IO::Handle ();
 use IO::Socket::UNIX;
@@ -658,9 +658,7 @@ SKIP: {
 
 # ensure compatibility with other PSGI servers
 SKIP: {
-	require_mods(@zmods, qw(Plack::Test HTTP::Request::Common), 3);
-	use_ok 'HTTP::Request::Common';
-	use_ok 'Plack::Test';
+	require_mods @zmods, 'psgi', 3;
 	STDERR->flush;
 	open my $olderr, '>&', \*STDERR or die "dup stderr: $!";
 	open my $tmperr, '+>', undef or die;
diff --git a/t/httpd-https.t b/t/httpd-https.t
index bf086123..142a7a56 100644
--- a/t/httpd-https.t
+++ b/t/httpd-https.t
@@ -6,7 +6,7 @@ use Socket qw(SOCK_STREAM IPPROTO_TCP SOL_SOCKET);
 use PublicInbox::TestCommon;
 use File::Copy qw(cp);
 # IO::Poll is part of the standard library, but distros may split them off...
-require_mods(qw(IO::Socket::SSL IO::Poll Plack::Util));
+require_mods qw(IO::Socket::SSL IO::Poll -httpd);
 my @certs = qw(certs/server-cert.pem certs/server-key.pem
 	certs/server2-cert.pem certs/server2-key.pem);
 if (scalar(grep { -r $_ } @certs) != scalar(@certs)) {
diff --git a/t/httpd-unix.t b/t/httpd-unix.t
index 0b620bd6..d4d50528 100644
--- a/t/httpd-unix.t
+++ b/t/httpd-unix.t
@@ -8,7 +8,7 @@ use Errno qw(EADDRINUSE);
 use Cwd qw(abs_path);
 use Carp qw(croak);
 use autodie qw(close);
-require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
+require_mods qw(-httpd);
 use IO::Socket::UNIX;
 use POSIX qw(mkfifo);
 require PublicInbox::Sigfd;
diff --git a/t/httpd.t b/t/httpd.t
index c0fbaa22..39382b85 100644
--- a/t/httpd.t
+++ b/t/httpd.t
@@ -1,12 +1,12 @@
 #!perl -w
-# Copyright (C) 2016-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict;
 use v5.10.1;
 use PublicInbox::TestCommon;
 use PublicInbox::Eml;
 use Socket qw(IPPROTO_TCP SOL_SOCKET);
-require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
+require_mods '-httpd';
 require_git_http_backend;
 
 # FIXME: too much setup
diff --git a/t/plack.t b/t/plack.t
index 07cab12a..131ce432 100644
--- a/t/plack.t
+++ b/t/plack.t
@@ -5,9 +5,7 @@ use strict;
 use v5.10.1;
 use PublicInbox::TestCommon;
 my $psgi = "./examples/public-inbox.psgi";
-my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape);
-require_mods(@mods);
-foreach my $mod (@mods) { use_ok $mod; }
+require_mods 'psgi';
 ok(-f $psgi, "psgi example file found");
 my ($tmpdir, $for_destroy) = tmpdir();
 my $pfx = 'http://example.com/test';
diff --git a/t/psgi_attach.t b/t/psgi_attach.t
index db551696..6c769d85 100644
--- a/t/psgi_attach.t
+++ b/t/psgi_attach.t
@@ -4,9 +4,7 @@
 use strict;
 use v5.10.1;
 use PublicInbox::TestCommon;
-my @mods = qw(HTTP::Request::Common Plack::Builder Plack::Test URI::Escape);
-require_mods(@mods);
-use_ok $_ foreach @mods;
+require_mods 'psgi';
 use_ok 'PublicInbox::WWW';
 use PublicInbox::Config;
 use PublicInbox::Eml;
diff --git a/t/psgi_bad_mids.t b/t/psgi_bad_mids.t
index ac0eb3c3..56381a35 100644
--- a/t/psgi_bad_mids.t
+++ b/t/psgi_bad_mids.t
@@ -4,11 +4,8 @@
 use v5.12;
 use PublicInbox::TestCommon;
 use PublicInbox::Eml;
-my @mods = qw(DBD::SQLite HTTP::Request::Common Plack::Test
-		URI::Escape Plack::Builder);
-require_git 2.6;
-require_mods(@mods);
-use_ok($_) for @mods;
+require_git v2.6;
+require_mods qw(DBD::SQLite psgi);
 use_ok 'PublicInbox::WWW';
 my $msgs = <<'';
 F1V5OR6NMF.3M649JTLO9IXD@tux.localdomain/hehe1"'<foo
diff --git a/t/psgi_mount.t b/t/psgi_mount.t
index e43b9f2d..7117cda3 100644
--- a/t/psgi_mount.t
+++ b/t/psgi_mount.t
@@ -6,10 +6,7 @@ use PublicInbox::Eml;
 use PublicInbox::TestCommon;
 my ($tmpdir, $for_destroy) = tmpdir();
 my $v1dir = "$tmpdir/v1.git";
-my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape
-	Plack::Builder Plack::App::URLMap);
-require_mods(@mods);
-use_ok $_ foreach @mods;
+require_mods 'psgi';
 use_ok 'PublicInbox::WWW';
 my $ibx = create_inbox 'test', tmpdir => $v1dir, sub {
 	my ($im, $ibx) = @_;
diff --git a/t/psgi_multipart_not.t b/t/psgi_multipart_not.t
index e7c43abf..4b3b93fa 100644
--- a/t/psgi_multipart_not.t
+++ b/t/psgi_multipart_not.t
@@ -5,10 +5,7 @@ use v5.12;
 use PublicInbox::TestCommon;
 use PublicInbox::Eml;
 require_git 2.6;
-my @mods = qw(DBD::SQLite Xapian HTTP::Request::Common
-              Plack::Test URI::Escape Plack::Builder Plack::Test);
-require_mods(@mods);
-use_ok($_) for (qw(HTTP::Request::Common Plack::Test));
+require_mods qw(DBD::SQLite Xapian psgi);
 use_ok 'PublicInbox::WWW';
 my $ibx = create_inbox 'v2', version => 2, sub {
 	my ($im) = @_;
diff --git a/t/psgi_scan_all.t b/t/psgi_scan_all.t
index 4c28b553..7c697854 100644
--- a/t/psgi_scan_all.t
+++ b/t/psgi_scan_all.t
@@ -4,11 +4,10 @@
 use v5.12;
 use PublicInbox::TestCommon;
 use PublicInbox::Eml;
-my @use = qw(HTTP::Request::Common Plack::Test);
 my @req = qw(URI::Escape DBD::SQLite);
 require_git v2.6;
-require_mods(@use, @req, qw(PublicInbox::WWW));
-$_->import for @use;
+require_mods qw(DBD::SQLite psgi);
+use_ok 'PublicInbox::WWW';
 my $cfgtxt = '';
 foreach my $i (1..2) {
 	my $ibx = create_inbox "test-$i", version => 2, indexlevel => 'basic',
diff --git a/t/psgi_search.t b/t/psgi_search.t
index 759dab78..8d47356e 100644
--- a/t/psgi_search.t
+++ b/t/psgi_search.t
@@ -6,10 +6,7 @@ use PublicInbox::TestCommon;
 use IO::Uncompress::Gunzip qw(gunzip);
 use PublicInbox::Eml;
 use PublicInbox::Inbox;
-my @mods = qw(DBD::SQLite Xapian HTTP::Request::Common Plack::Test
-		URI::Escape Plack::Builder);
-require_mods(@mods);
-use_ok($_) for (qw(HTTP::Request::Common Plack::Test));
+require_mods qw(DBD::SQLite Xapian psgi);
 use_ok 'PublicInbox::WWW';
 use_ok 'PublicInbox::SearchIdx';
 my ($tmpdir, $for_destroy) = tmpdir();
diff --git a/t/psgi_text.t b/t/psgi_text.t
index b8b1bc48..deb41f9f 100644
--- a/t/psgi_text.t
+++ b/t/psgi_text.t
@@ -8,8 +8,7 @@ my ($tmpdir, $for_destroy) = tmpdir();
 my $maindir = "$tmpdir/main.git";
 my $addr = 'test-public@example.com';
 my $cfgpfx = "publicinbox.test";
-my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape Plack::Builder);
-use_ok $_ foreach @mods;
+require_mods qw(psgi);
 use PublicInbox::Import;
 use_ok 'PublicInbox::WWW';
 use_ok 'PublicInbox::WwwText';
diff --git a/t/psgi_v2.t b/t/psgi_v2.t
index 2b678fd8..2027037d 100644
--- a/t/psgi_v2.t
+++ b/t/psgi_v2.t
@@ -10,9 +10,7 @@ use PublicInbox::Eml;
 use PublicInbox::Config;
 use PublicInbox::MID qw(mids);
 use autodie qw(kill rename);
-require_mods(qw(DBD::SQLite Xapian HTTP::Request::Common Plack::Test
-		URI::Escape Plack::Builder HTTP::Date));
-use_ok($_) for (qw(HTTP::Request::Common Plack::Test));
+require_mods qw(DBD::SQLite Xapian psgi);
 use_ok 'PublicInbox::WWW';
 my ($tmpdir, $for_destroy) = tmpdir();
 my $enc_dup = 'ref-20150309094050.GO3427@x1.example';
diff --git a/t/solver_git.t b/t/solver_git.t
index db672904..694e2671 100644
--- a/t/solver_git.t
+++ b/t/solver_git.t
@@ -7,7 +7,7 @@ use Cwd qw(abs_path);
 require_git v2.6;
 use PublicInbox::ContentHash qw(git_sha);
 use PublicInbox::Spawn qw(run_qx);
-require_mods(qw(DBD::SQLite Xapian URI::Escape));
+require_mods(qw(DBD::SQLite Xapian));
 require PublicInbox::SolverGit;
 my $rdr = { 2 => \(my $null) };
 my $git_dir = xqx([qw(git rev-parse --git-common-dir)], undef, $rdr);
@@ -208,10 +208,8 @@ my $hinted = $res;
 shift @$res; shift @$hinted;
 is_deeply($res, $hinted, 'hints work (or did not hurt :P');
 
-my @psgi = qw(HTTP::Request::Common Plack::Test Plack::Builder);
 SKIP: {
-	require_mods(@psgi, 7 + scalar(@psgi));
-	use_ok($_) for @psgi;
+	require_mods qw(psgi 1);
 	require PublicInbox::WWW;
 	my $binfoo = "$ibx->{inboxdir}/binfoo.git";
 	my $l = "$ibx->{inboxdir}/inbox.lock";
diff --git a/t/v2mirror.t b/t/v2mirror.t
index b8824182..dd4d9a6c 100644
--- a/t/v2mirror.t
+++ b/t/v2mirror.t
@@ -13,8 +13,7 @@ local $ENV{HOME} = abs_path('t');
 use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
 
 # Integration tests for HTTP cloning + mirroring
-require_mods(qw(Plack::Util Plack::Builder
-		HTTP::Date HTTP::Status Xapian DBD::SQLite));
+require_mods qw(psgi -httpd Xapian DBD::SQLite);
 use_ok 'PublicInbox::V2Writable';
 use PublicInbox::InboxWritable;
 use PublicInbox::Eml;
diff --git a/t/www_altid.t b/t/www_altid.t
index 6f0f0c61..c06e34d9 100644
--- a/t/www_altid.t
+++ b/t/www_altid.t
@@ -5,12 +5,12 @@ use strict; use v5.10.1; use PublicInbox::TestCommon;
 use PublicInbox::Config;
 use PublicInbox::Spawn qw(spawn);
 require_cmd('sqlite3');
-require_mods(qw(DBD::SQLite HTTP::Request::Common Plack::Test URI::Escape
-	Plack::Builder IO::Uncompress::Gunzip Xapian));
+require_mods qw(DBD::SQLite psgi Xapian);
 use_ok($_) for qw(Plack::Test HTTP::Request::Common);
 require_ok 'PublicInbox::Msgmap';
 require_ok 'PublicInbox::AltId';
 require_ok 'PublicInbox::WWW';
+require IO::Uncompress::Gunzip;
 my ($tmpdir, $for_destroy) = tmpdir();
 my $aid = 'xyz';
 my $cfgpath;
diff --git a/t/www_listing.t b/t/www_listing.t
index e0d21161..ff75655d 100644
--- a/t/www_listing.t
+++ b/t/www_listing.t
@@ -5,7 +5,7 @@
 use v5.12; use PublicInbox::TestCommon;
 use PublicInbox::Import;
 use IO::Uncompress::Gunzip qw(gunzip);
-require_mods(qw(json URI::Escape Plack::Builder HTTP::Tiny));
+require_mods qw(json URI::Escape psgi -httpd HTTP::Tiny);
 my $curl = require_cmd 'curl';
 require PublicInbox::WwwListing;
 require PublicInbox::ManifestJsGz;
diff --git a/t/www_static.t b/t/www_static.t
index 3281751c..83a96a5e 100644
--- a/t/www_static.t
+++ b/t/www_static.t
@@ -6,8 +6,8 @@ use Test::More;
 use PublicInbox::TestCommon;
 my ($tmpdir, $for_destroy) = tmpdir();
 my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape);
-require_mods(@mods, 'IO::Uncompress::Gunzip');
-use_ok $_ foreach @mods;
+require_mods qw(psgi);
+require IO::Uncompress::Gunzip;
 use_ok 'PublicInbox::WwwStatic';
 
 my $app = sub {

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] www: test address URL-fication
  2024-09-16 21:02 [PATCH 0/4] www: PSGI test fixes + URL-fication tests Eric Wong
                   ` (2 preceding siblings ...)
  2024-09-16 21:03 ` [PATCH 3/4] test_common: improve psgi test setup + loading Eric Wong
@ 2024-09-16 21:03 ` Eric Wong
  3 siblings, 0 replies; 5+ messages in thread
From: Eric Wong @ 2024-09-16 21:03 UTC (permalink / raw)
  To: meta

Probably more tests coming, but setup stuff is still on the slow
side.  While email addresses can be all sorts of uncommon
characters, I'm also fairly certain we can disallow the [&;<>]
set from being URL-fied.
---
 MANIFEST                |  1 +
 lib/PublicInbox/View.pm |  2 +-
 t/psgi_urlfication.t    | 71 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 t/psgi_urlfication.t

diff --git a/MANIFEST b/MANIFEST
index 34d3ef14..3c4cefb4 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -589,6 +589,7 @@ t/psgi_multipart_not.t
 t/psgi_scan_all.t
 t/psgi_search.t
 t/psgi_text.t
+t/psgi_urlfication.t
 t/psgi_v2-new.eml
 t/psgi_v2-old.eml
 t/psgi_v2.t
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 5d474292..275258e3 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -74,7 +74,7 @@ sub addr2urlmap ($) {
 		while (my ($addr, $ibx) = each %$by_addr) {
 			# FIXME: use negative look(behind|ahead) in s// for
 			# `&' and `;' to make them not match \b
-			next if $addr =~ /\A(?:gt|lt|#[0-9]+)\z/;
+			next if $addr =~ /\A(?:[&;<>]|gt|lt|#[0-9]+)\z/;
 			$url = $ibx->base_url // $ibx->base_url($ctx->{env});
 			$addr2url{ascii_html($addr)} = ascii_html($url) if
 				defined $url
diff --git a/t/psgi_urlfication.t b/t/psgi_urlfication.t
new file mode 100644
index 00000000..673ded9f
--- /dev/null
+++ b/t/psgi_urlfication.t
@@ -0,0 +1,71 @@
+#!perl -w
+# Copyright (C) all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+# corner cases to abuse URL-fication
+use v5.12; use PublicInbox::TestCommon;
+use autodie;
+use PublicInbox::IO qw(write_file);
+require_mods(qw(DBD::SQLite Xapian psgi -httpd));
+require PublicInbox::Eml;
+require PublicInbox::WWW;
+
+my $ibx_a = create_inbox 'a', indexlevel => 'basic', sub {
+	my ($im, $ibx) = @_;
+	$im->add(PublicInbox::Eml->new(<<EOM)) or xbail;
+Date: Fri, 02 Oct 1993 00:00:04 +0000
+From: a\@example.com
+Message-ID: <xpost-addr-urlfic\@tion>
+To: <$ibx->{-primary_address}>
+Cc: <;>, <"foo>">, <amp&amp\@wtf>, <gt>, "<", ">", <lt>,
+	somethingelse\@example.com
+EOM
+};
+
+my $ibx_b = create_inbox 'b', indexlevel => 'basic', sub {
+	my ($im, $ibx) = @_;
+	$im->add(PublicInbox::Eml->new(<<EOM)) or xbail;
+Date: Fri, 02 Oct 1993 00:00:00 +0000
+Message-ID: <wh\@tever>
+From: b\@example.com
+To: <$ibx->{-primary_address}>
+Cc: <$ibx_a->{-primary_address}>
+EOM
+};
+
+my $tmpdir = tmpdir;
+my $cfgpath = "$tmpdir/public-inbox.config";
+
+write_file '>', $cfgpath, <<EOM;
+[publicinbox]
+	nameIsUrl = true
+[publicinbox "a"]
+	inboxdir = $ibx_a->{inboxdir}
+	address = $ibx_a->{-primary_address}
+	address = somethingelse\@example.com
+[publicinbox "b"]
+	inboxdir = $ibx_b->{inboxdir}
+	address = $ibx_b->{-primary_address}
+	address = ";"
+	address = &
+	address = gt
+	address = >
+	address = <
+EOM
+my $cfg = PublicInbox::Config->new($cfgpath);
+my $www = PublicInbox::WWW->new($cfg);
+my $env = { TMPDIR => "$tmpdir", PI_CONFIG => $cfgpath };
+my $client = sub {
+	my ($cb) = @_;
+	my $res = $cb->(GET('/a/xpost-addr-urlfic@tion/'));
+	my $content = $res->content;
+	for my $c ('&', ';', '<', '>') {
+		unlike $content, qr/>$c</s, "no bare `$c' from URL-ification";
+	}
+	like $content, qr/>somethingelse\@example\.com</s,
+		'address linkified';
+};
+
+test_psgi(sub { $www->call(@_) }, $client);
+test_httpd $env, $client;
+
+done_testing;

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-09-16 21:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-16 21:02 [PATCH 0/4] www: PSGI test fixes + URL-fication tests Eric Wong
2024-09-16 21:02 ` [PATCH 1/4] config: ignore blank address= and listid= entries Eric Wong
2024-09-16 21:02 ` [PATCH 2/4] test_common: -httpd requires HTTP::{Date,Status} Eric Wong
2024-09-16 21:03 ` [PATCH 3/4] test_common: improve psgi test setup + loading Eric Wong
2024-09-16 21:03 ` [PATCH 4/4] www: test address URL-fication Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).