lib/PublicInbox/HTTP.pm | 17 ++++++++--------- lib/PublicInbox/ManifestJsGz.pm | 3 +-- lib/PublicInbox/NNTP.pm | 2 +- lib/PublicInbox/View.pm | 5 ++--- lib/PublicInbox/ViewVCS.pm | 5 ++--- lib/PublicInbox/WWW.pm | 10 ++++------ lib/PublicInbox/WwwAttach.pm | 4 ++-- lib/PublicInbox/WwwHighlight.pm | 5 ++--- lib/PublicInbox/WwwListing.pm | 4 ++-- lib/PublicInbox/WwwStatic.pm | 4 ++-- lib/PublicInbox/WwwStream.pm | 4 ++-- lib/PublicInbox/WwwText.pm | 5 ++--- t/psgi_search.t | 1 - t/search-thr-index.t | 8 ++++---- t/www_listing.t | 19 +++++++++++++++---- xt/cmp-msgstr.t | 2 +- diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm index d0708c5be4caf0a31740d5b23266ca32cf0bd3d7..b2c74cf378dcba2ab3f3cd3b6f9578ddb7feab58 100644 --- a/lib/PublicInbox/HTTP.pm +++ b/lib/PublicInbox/HTTP.pm @@ -21,7 +21,6 @@ # 2: keep connection, chunk responses package PublicInbox::HTTP; use strict; use parent qw(PublicInbox::DS); -use bytes (); # only for bytes::length use Fcntl qw(:seek); use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl use Plack::Util; @@ -89,7 +88,7 @@ # otherwise we can be buffering infinitely w/o backpressure return read_input($self) if ref($self->{env}); my $rbuf = $self->{rbuf} // (\(my $x = '')); - $self->do_read($rbuf, 8192, bytes::length($$rbuf)) or return; + $self->do_read($rbuf, 8192, length($$rbuf)) or return; rbuf_process($self, $rbuf); } @@ -104,7 +103,7 @@ # We do not support Trailers in chunked requests, for now # (they are rarely-used and git (as of 2.7.2) does not use them) if ($r == -1 || $env{HTTP_TRAILER} || # this length-check is necessary for PURE_PERL=1: - ($r == -2 && bytes::length($$rbuf) > 0x4000)) { + ($r == -2 && length($$rbuf) > 0x4000)) { return quit($self, 400); } if ($r < 0) { # incomplete @@ -121,7 +120,7 @@ # IO::Handle::write returns boolean, this returns bytes written: sub xwrite ($$$) { my ($fh, $rbuf, $max) = @_; - my $w = bytes::length($$rbuf); + my $w = length($$rbuf); $w = $max if $w > $max; $fh->write($$rbuf, $w) or return; $w; @@ -236,7 +235,7 @@ # middlewares such as Deflater may write empty strings sub chunked_write ($$) { my $self = $_[0]; return if $_[1] eq ''; - msg_more($self, sprintf("%x\r\n", bytes::length($_[1]))); + msg_more($self, sprintf("%x\r\n", length($_[1]))); msg_more($self, $_[1]); # use $self->write(\"\n\n") if you care about real-time @@ -411,12 +410,12 @@ if ($len == CHUNK_ZEND) { $$rbuf =~ s/\A\r\n//s and return app_dispatch($self, $input, $rbuf); - return quit($self, 400) if bytes::length($$rbuf) > 2; + return quit($self, 400) if length($$rbuf) > 2; } if ($len == CHUNK_END) { if ($$rbuf =~ s/\A\r\n//s) { $len = CHUNK_START; - } elsif (bytes::length($$rbuf) > 2) { + } elsif (length($$rbuf) > 2) { return quit($self, 400); } } @@ -426,14 +425,14 @@ $len = hex $1; if (($len + -s $input) > $MAX_REQUEST_BUFFER) { return quit($self, 413); } - } elsif (bytes::length($$rbuf) > CHUNK_MAX_HDR) { + } elsif (length($$rbuf) > CHUNK_MAX_HDR) { return quit($self, 400); } # will break from loop since $len >= 0 } if ($len < 0) { # chunk header is trickled, read more - $self->do_read($rbuf, 8192, bytes::length($$rbuf)) or + $self->do_read($rbuf, 8192, length($$rbuf)) or return recv_err($self, $len); # (implicit) goto chunk_start if $r > 0; } diff --git a/lib/PublicInbox/ManifestJsGz.pm b/lib/PublicInbox/ManifestJsGz.pm index 7fee78dd15417958afb5e37a262c848884ea71b5..69d81fa1ace13dc634625e86abd4c15935c57230 100644 --- a/lib/PublicInbox/ManifestJsGz.pm +++ b/lib/PublicInbox/ManifestJsGz.pm @@ -6,7 +6,6 @@ package PublicInbox::ManifestJsGz; use strict; use v5.10.1; use parent qw(PublicInbox::WwwListing); -use bytes (); # length use PublicInbox::Config; use IO::Compress::Gzip qw(gzip); use HTTP::Date qw(time2str); @@ -108,7 +107,7 @@ $manifest = $json->encode($manifest); gzip(\$manifest => \(my $out)); [ 200, [ qw(Content-Type application/gzip), 'Last-Modified', time2str($ctx->{-mtime}), - 'Content-Length', bytes::length($out) ], [ $out ] ] + 'Content-Length', length($out) ], [ $out ] ] } sub per_inbox { diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 13a68bb86af8690b4c6b703d80fadfad332b8345..aea04c05464b28b30d5e8d7a713e5da0446c9282 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -241,7 +241,7 @@ $gmt =~ /\A(?:UTC|GMT)\z/i or die "GM invalid: $gmt"; $gmt = 1; } my ($YYYY, $MM, $DD); - if (bytes::length($date) == 8) { # RFC 3977 allows YYYYMMDD + if (length($date) == 8) { # RFC 3977 allows YYYYMMDD ($YYYY, $MM, $DD) = unpack('A4A2A2', $date); } else { # legacy clients send YYMMDD my $YY; diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index 17d38302f3d58b42082f6206138ddd3a7ee8f027..94ea614894e9d653926c3b89224f01a22b2f0684 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -5,8 +5,7 @@ # Used for displaying the HTML web interface. # See Documentation/design_www.txt for this. package PublicInbox::View; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use List::Util qw(max); use PublicInbox::MsgTime qw(msg_datestamp); use PublicInbox::Hval qw(ascii_html obfuscate_addrs prurl mid_href @@ -531,7 +530,7 @@ # downloads for 0-byte multipart attachments return unless $part->{bdy}; my $nl = $idx eq '1' ? '' : "\n"; # like join("\n", ...) - my $size = bytes::length($part->body); + my $size = length($part->body); # hide attributes normally, unless we want to aid users in # spotting MUA problems: diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm index 702a075d3365089e76c7eaf8e58579c0c6dd1721..6365f04547bca74359c611ea307a9b4f8f2f10be 100644 --- a/lib/PublicInbox/ViewVCS.pm +++ b/lib/PublicInbox/ViewVCS.pm @@ -15,8 +15,7 @@ # patches apply 100% cleanly to published blobs). package PublicInbox::ViewVCS; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use PublicInbox::SolverGit; use PublicInbox::WwwStream qw(html_oneshot); use PublicInbox::Linkify; @@ -49,7 +48,7 @@ html_page($ctx, 500, $logref); } elsif (index($$bref, "\0") >= 0) { [200, [qw(Content-Type application/octet-stream), @cl] ]; } else { - my $n = bytes::length($$bref); + my $n = length($$bref); if ($n >= $BIN_DETECT || $n == $size) { return [200, [ 'Content-Type', 'text/plain; charset=UTF-8', @cl ] ]; diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 1afdece0f39f5a946a09961cbd194d456f1dcc51..570e690ec8136ca7cf6c98b4ea0138da42c57032 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -11,10 +11,8 @@ # - No JavaScript, graphics or icons allowed. # - Must not rely on static content # - UTF-8 is only for user-content, 7-bit US-ASCII for us package PublicInbox::WWW; -use 5.010_001; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use PublicInbox::Config; use PublicInbox::Hval; use URI::Escape qw(uri_unescape); @@ -646,8 +644,7 @@ my $env = $ctx->{env}; $css = PublicInbox::UserContent::sample($ctx->{ibx}, $env); } defined $css or return r404(); - my $h = [ 'Content-Length', bytes::length($css), - 'Content-Type', 'text/css' ]; + my $h = [ 'Content-Length', length($css), 'Content-Type', 'text/css' ]; PublicInbox::GitHTTPBackend::cache_one_year($h); [ 200, $h, [ $css ] ]; } @@ -656,7 +653,8 @@ sub get_description { my ($ctx, $inbox) = @_; invalid_inbox($ctx, $inbox) || do { my $d = $ctx->{ibx}->description . "\n"; - [ 200, [ 'Content-Length', bytes::length($d), + utf8::encode($d); + [ 200, [ 'Content-Length', length($d), 'Content-Type', 'text/plain' ], [ $d ] ]; }; } diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index a6c68a3fbd91d5310325e058413bcb510776ffaa..c17394afe8709b61caae9315f549d53c84ad758d 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -4,8 +4,8 @@ # For retrieving attachments from messages in the WWW interface package PublicInbox::WwwAttach; # internal package use strict; +use v5.10.1; use parent qw(PublicInbox::GzipFilter); -use bytes (); # only for bytes::length use PublicInbox::Eml; sub referer_match ($) { @@ -50,7 +50,7 @@ $res->[1]->[1] = 'text/plain'; $part = "Deep-linking prevented\n"; } } - push @{$res->[1]}, 'Content-Length', bytes::length($part); + push @{$res->[1]}, 'Content-Length', length($part); $res->[2]->[0] = $part; } diff --git a/lib/PublicInbox/WwwHighlight.pm b/lib/PublicInbox/WwwHighlight.pm index 6fed2fedd1edac589046a29c62160d3b69637021..3593c2d49e3f6342e52c31fd8eee46214e2c0477 100644 --- a/lib/PublicInbox/WwwHighlight.pm +++ b/lib/PublicInbox/WwwHighlight.pm @@ -20,8 +20,7 @@ # curl -HExpect: -T /path/to/file http://example.com/x.c package PublicInbox::WwwHighlight; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use parent qw(PublicInbox::HlMod); use PublicInbox::Linkify qw(); use PublicInbox::Hval qw(ascii_html); @@ -69,7 +68,7 @@ } $l->linkify_2($$bref); my $h = [ 'Content-Type', 'text/html; charset=UTF-8' ]; - push @$h, 'Content-Length', bytes::length($$bref); + push @$h, 'Content-Length', length($$bref); [ 200, $h, [ $$bref ] ] } diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm index a31aa4ca1ba934cd8472c2f8b9fb038f2b126f8f..8b54d7249aad85538789b25668d86f5dbcabdf0b 100644 --- a/lib/PublicInbox/WwwListing.pm +++ b/lib/PublicInbox/WwwListing.pm @@ -5,12 +5,12 @@ # Provide an HTTP-accessible listing of inboxes. # Used by PublicInbox::WWW package PublicInbox::WwwListing; use strict; +use v5.10.1; use PublicInbox::Hval qw(prurl fmt_ts ascii_html); use PublicInbox::Linkify; use PublicInbox::GzipFilter qw(gzf_maybe); use PublicInbox::ConfigIter; use PublicInbox::WwwStream; -use bytes (); # bytes::length sub ibx_entry { my ($ctx, $ibx, $ce) = @_; @@ -213,7 +213,7 @@ } my $out = $gzf->zflush('
'.
 			PublicInbox::WwwStream::code_footer($ctx->{env}) .
 			'
'); - $h->[3] = bytes::length($out); + $h->[3] = length($out); [ $code, $h, [ $out ] ]; } diff --git a/lib/PublicInbox/WwwStatic.pm b/lib/PublicInbox/WwwStatic.pm index 29e4819dfc4b51e52fa5d8baec2a1c5ffb7b82f1..b3476ab82e0922eb9c8f99ca5690016a30806571 100644 --- a/lib/PublicInbox/WwwStatic.pm +++ b/lib/PublicInbox/WwwStatic.pm @@ -9,8 +9,8 @@ # It encapsulates the "autoindex", "index", and "gzip_static" # functionality of nginx. package PublicInbox::WwwStatic; use strict; +use v5.10.1; use parent qw(Exporter); -use bytes (); use Fcntl qw(SEEK_SET O_RDONLY O_NONBLOCK); use POSIX qw(strftime); use HTTP::Date qw(time2str); @@ -318,7 +318,7 @@ ${$self->{style}} . "
Index of $path_info_html

\n");
 	$gzf->zmore(join("\n", @entries));
 	my $out = $gzf->zflush("

\n"); - $h->[3] = bytes::length($out); + $h->[3] = length($out); [ 200, $h, [ $out ] ] } diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm index 2f8212d4a917d651802f2e78e0df36e430e90396..adcb5fe24314305c436e07048983c6dbaf8d9401 100644 --- a/lib/PublicInbox/WwwStream.pm +++ b/lib/PublicInbox/WwwStream.pm @@ -7,9 +7,9 @@ # # See PublicInbox::GzipFilter parent class for more info. package PublicInbox::WwwStream; use strict; +use v5.10.1; use parent qw(Exporter PublicInbox::GzipFilter); our @EXPORT_OK = qw(html_oneshot); -use bytes (); # length use PublicInbox::Hval qw(ascii_html prurl ts2str); our $TOR_URL = 'https://www.torproject.org/'; our $CODE_URL = [ qw(http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git @@ -216,7 +216,7 @@ base_url($ctx); }; $ctx->zmore($$sref) if $sref; my $bdy = $ctx->zflush(_html_end($ctx)); - $res_hdr->[3] = bytes::length($bdy); + $res_hdr->[3] = length($bdy); [ $code, $res_hdr, [ $bdy ] ] } diff --git a/lib/PublicInbox/WwwText.pm b/lib/PublicInbox/WwwText.pm index 76a95a6b640c879083b5010458a803dee4f815a7..db5060eaa460bf002c4377b93eb1b14c1cd5c7ba 100644 --- a/lib/PublicInbox/WwwText.pm +++ b/lib/PublicInbox/WwwText.pm @@ -4,8 +4,7 @@ # used for displaying help texts and other non-mail content package PublicInbox::WwwText; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use PublicInbox::Linkify; use PublicInbox::WwwStream; use PublicInbox::Hval qw(ascii_html); @@ -43,7 +42,7 @@ my $gzf = gzf_maybe($hdr, $env); $txt = $gzf->translate($txt); $txt .= $gzf->zflush; } - $hdr->[3] = bytes::length($txt); + $hdr->[3] = length($txt); return [ $code, $hdr, [ $txt ] ] } diff --git a/t/psgi_search.t b/t/psgi_search.t index 5bdd66edf2bee703e68fd5646d34cc4821dd6d54..3da93eda718cd7335c2b1f747f2a7f16e2bf880e 100644 --- a/t/psgi_search.t +++ b/t/psgi_search.t @@ -8,7 +8,6 @@ use IO::Uncompress::Gunzip qw(gunzip); use PublicInbox::Eml; use PublicInbox::Config; use PublicInbox::Inbox; -use bytes (); # only for bytes::length my @mods = qw(DBD::SQLite Search::Xapian HTTP::Request::Common Plack::Test URI::Escape Plack::Builder); require_mods(@mods); diff --git a/t/search-thr-index.t b/t/search-thr-index.t index fc1b666a39da185929877939515388aa507e8457..62745dbce1d5122db18164999addb4902e43812e 100644 --- a/t/search-thr-index.t +++ b/t/search-thr-index.t @@ -1,8 +1,8 @@ +#!perl -w # Copyright (C) 2017-2021 all contributors # License: AGPL-3.0+ use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use Test::More; use PublicInbox::TestCommon; use PublicInbox::MID qw(mids); @@ -45,7 +45,7 @@ $_ .= "\n"; my $mime = PublicInbox::Eml->new(\$_); $mime->header_set('From' => 'bw@g'); $mime->header_set('To' => 'git@vger.kernel.org'); - my $bytes = bytes::length($mime->as_string); + my $bytes = length($mime->as_string); my $mid = mids($mime->header_obj)->[0]; my $smsg = bless { bytes => $bytes, @@ -92,7 +92,7 @@ my $num = $reidx->{num}; my $tid0 = $dbh->selectrow_array(<<'', undef, $num); SELECT tid FROM over WHERE num = ? LIMIT 1 - my $bytes = bytes::length($mime->as_string); + my $bytes = length($mime->as_string); my $mid = mids($mime->header_obj)->[0]; my $smsg = bless { bytes => $bytes, diff --git a/t/www_listing.t b/t/www_listing.t index 6b3b408fae413f498fba880b10321e493765e780..7ea12eea3712e292feed1b55b70b0852aded4d1a 100644 --- a/t/www_listing.t +++ b/t/www_listing.t @@ -55,7 +55,7 @@ my $manifest = $json->decode($tmp); ok(my $clone = $manifest->{'/alt'}, '/alt in manifest'); is($clone->{owner}, "lorelei \x{100}", 'owner set'); is($clone->{reference}, '/bare', 'reference detected'); - is($clone->{description}, "we're all clones", 'description read'); + is($clone->{description}, "we're \x{100}ll clones", 'description read'); ok(my $bare = $manifest->{'/bare'}, '/bare in manifest'); is($bare->{description}, 'Unnamed repository', 'missing $GIT_DIR/description fallback'); @@ -72,6 +72,10 @@ 'epoch 0 in description'); ok(my $v2epoch1 = $manifest->{'/v2/git/1.git'}, 'v2 epoch 1 appeared'); like($v2epoch1->{description}, qr/ \[epoch 1\]\z/, 'epoch 1 in description'); + + $res = $http->get("http://$host:$port/alt/description"); + is($res->{content}, "we're \xc4\x80ll clones\n", 'UTF-8 description') + or diag explain($res); } my $td; @@ -91,9 +95,9 @@ for my $i (0..2) { is(xsys(@clone, $alt, "$v2/git/$i.git"), 0, "clone epoch $i") } ok(open(my $fh, '>', "$v2/inbox.lock"), 'mock a v2 inbox'); - open $fh, '>', "$alt/description" or die; - print $fh "we're all clones\n" or die; - close $fh or die; + open $fh, '>', "$alt/description" or xbail "open $alt/description $!"; + print $fh "we're \xc4\x80ll clones\n" or xbail "print $!"; + close $fh or xbail "write: $alt/description $!"; is(xsys('git', "--git-dir=$alt", qw(config gitweb.owner), "lorelei \xc4\x80"), 0, 'set gitweb user'); @@ -178,6 +182,13 @@ is($? >> 8, 0, 'grok-pull exit code as expected'); for (qw(v2/git/0.git v2/git/1.git v2/git/2.git)) { ok(-d "$tmpdir/per-inbox/$_", "grok-pull created $_"); } + $td->kill; + $td->join; + is($?, 0, 'no error in exited process'); + open $fh, '<', $err or BAIL_OUT("open $err failed: $!"); + my $eout = do { local $/; <$fh> }; + unlike($eout, qr/wide/i, 'no Wide character warnings'); + unlike($eout, qr/uninitialized/i, 'no uninitialized warnings'); } done_testing(); diff --git a/xt/cmp-msgstr.t b/xt/cmp-msgstr.t index e0e8ed5a396d9cf8e9b1f4a38507dba3b92a2f99..900127c76cae85dcbc033308105196a4e3c220fd 100644 --- a/xt/cmp-msgstr.t +++ b/xt/cmp-msgstr.t @@ -60,7 +60,7 @@ if ($part =~ /[^\p{XPosixPrint}\s]/s) { # binary my $dig = $dig_cls->new; $dig->add($part); push @$cmp_arg, "M: ".$dig->hexdigest; - push @$cmp_arg, "B: ".bytes::length($part); + push @$cmp_arg, "B: ".length($part); } else { $part =~ s/\s+\z//s; push @$cmp_arg, "X: ".$part;