# represents a header value in various forms. Used for HTML generation
# in our web interface(s)
package PublicInbox::Hval;
+use v5.10.1; # be careful about unicode_strings in v5.12;
use strict;
-use warnings;
use Encode qw(find_encoding);
use PublicInbox::MID qw/mid_clean mid_escape/;
use base qw/Exporter/;
our @EXPORT_OK = qw/ascii_html obfuscate_addrs to_filename src_escape
- to_attr prurl mid_href fmt_ts ts2str/;
+ to_attr prurl mid_href fmt_ts ts2str utf8_maybe/;
use POSIX qw(strftime);
my $enc_ascii = find_encoding('us-ascii');
# human-friendly format
sub fmt_ts ($) { strftime('%Y-%m-%d %k:%M', gmtime($_[0])) }
+sub utf8_maybe ($) {
+ utf8::decode($_[0]);
+ utf8::valid($_[0]) or utf8::encode($_[0]); # non-UTF-8 data exists
+}
+
1;
use POSIX qw(strftime);
use URI::Escape qw(uri_escape);
use Scalar::Util ();
-use PublicInbox::Hval qw(ascii_html);
+use PublicInbox::Hval qw(ascii_html utf8_maybe);
# git for-each-ref and log use different format fields :<
my $ATOM_FMT = '--pretty=tformat:'.join('%n',
my $is_tag = $self->{-is_tag};
my ($H, $ct, $an, $ae, $at, $s, $bdy);
while ($lbuf =~ s/\A([^\0]+)\0\n//s) {
- utf8::decode($bdy = $1);
+ utf8_maybe($bdy = $1);
if ($is_tag) {
my %r;
eval "$bdy";
use PublicInbox::WwwStatic qw(r);
use PublicInbox::Qspawn;
use PublicInbox::WwwStream qw(html_oneshot);
-use PublicInbox::Hval qw(ascii_html);
+use PublicInbox::Hval qw(ascii_html utf8_maybe);
sub rd_404_log {
my ($bref, $ctx) = @_;
$code = 404;
} else {
my ($H, $h, $s_as) = split(/ /, $$bref, 3);
- utf8::decode($s_as);
+ utf8_maybe($s_as);
my $x = uri_escape_path($ctx->{-path});
$s_as = ascii_html($s_as);
print $zfh <<EOM;
use parent qw(Exporter);
our @EXPORT_OK = qw(flush_diff uri_escape_path);
use URI::Escape qw(uri_escape_utf8);
-use PublicInbox::Hval qw(ascii_html to_attr);
+use PublicInbox::Hval qw(ascii_html to_attr utf8_maybe);
use PublicInbox::Git qw(git_unquote);
my $OID_NULL = '0{7,}';
}
}
if (!$dctx) {
- utf8::decode($after);
+ utf8_maybe($after);
diff_before_or_after($ctx, \$after);
}
} else {
use PublicInbox::View;
use PublicInbox::Eml;
use Text::Wrap qw(wrap);
-use PublicInbox::Hval qw(ascii_html to_filename prurl);
+use PublicInbox::Hval qw(ascii_html to_filename prurl utf8_maybe);
use POSIX qw(strftime);
my $hl = eval {
require PublicInbox::HlMod;
"git show error:$qsp_err");
}
my $l = PublicInbox::Linkify->new;
- utf8::decode($$bref);
+ utf8_maybe($$bref);
html_page($ctx, 200, '<pre>', $l->to_html($$bref), '</pre><hr>',
dbg_log($ctx));
}
sub cmt_title { # git->cat_async callback
my ($bref, $oid, $type, $size, $ctx) = @_;
- utf8::decode($$bref);
+ utf8_maybe($$bref);
my $title = $$bref =~ /\r?\n\r?\n([^\r\n]+)\r?\n?/ ? $1 : '';
push(@{$ctx->{-cmt_pt}} , ascii_html($title)) == @{$ctx->{-cmt_P}} and
cmt_finalize($ctx);
open my $fh, '<', "$ctx->{-tmp}/h" or
die "open $ctx->{-tmp}/h: $!";
chop(my $buf = do { local $/ = "\0"; <$fh> });
- utf8::decode($buf);
- utf8::valid($buf) or utf8::encode($buf); # non-UTF-8 commits exist
+ utf8_maybe($buf); # non-UTF-8 commits exist
chomp $buf;
my ($P, $p);
($P, $p, @{$ctx->{cmt_info}}) = split(/\n/, $buf, 9);
EOM
print $zfh "\n", $ctx->{-linkify}->to_html($bdy) if length($bdy);
$bdy = '';
- open my $fh, '<:utf8', "$ctx->{-tmp}/p" or
- die "open $ctx->{-tmp}/p: $!";
+ open my $fh, '<', "$ctx->{-tmp}/p" or die "open $ctx->{-tmp}/p: $!";
if (-s $fh > $MAX_SIZE) {
print $zfh "---\n patch is too large to show\n";
} else { # prepare flush_diff:
read($fh, $x, -s _);
+ utf8_maybe($x);
$ctx->{-apfx} = $ctx->{-spfx} = $upfx;
$x =~ s/\r?\n/\n/gs;
$ctx->{-anchors} = {} if $x =~ /^diff --git /sm;
undef $_;
($m, $t, $oid, $sz) = split(/ +/, $x, 4);
$m = $GIT_MODE{$m} // '?';
- utf8::decode($f);
+ utf8_maybe($f);
$n = ascii_html($f);
if ($m eq 'g') { # gitlink submodule commit
$$bref .= "\ng\t\t$n @ <a\nhref=#g>commit</a>$oid";
sub show_tag_result { # git->cat_async callback
my ($bref, $oid, $type, $size, $ctx) = @_;
- utf8::decode($$bref);
+ utf8_maybe($$bref);
my $l = PublicInbox::Linkify->new;
$$bref = $l->to_html($$bref);
$$bref =~ s!^object ([a-f0-9]+)!object <a
" $raw_more</pre>".dbg_log($ctx));
# TODO: detect + convert to ensure validity
- utf8::decode($$blob);
+ utf8_maybe($$blob);
my $nl = ($$blob =~ s/\r?\n/\n/sg);
my $pad = length($nl);
use PublicInbox::WwwStatic qw(r);
use PublicInbox::GitHTTPBackend;
use PublicInbox::WwwStream;
-use PublicInbox::Hval qw(ascii_html);
+use PublicInbox::Hval qw(ascii_html utf8_maybe);
use PublicInbox::ViewDiff qw(uri_escape_path);
use PublicInbox::RepoSnapshot;
use PublicInbox::RepoAtom;
sub capture { # psgi_qx callback to capture git-for-each-ref
my ($bref, $arg) = @_; # arg = [ctx, key, OnDestroy(summary_END)]
- utf8::decode($$bref);
+ utf8_maybe($$bref);
$arg->[0]->{qx_res}->{$arg->[1]} = $$bref;
# summary_END may be called via OnDestroy $arg->[2]
}
$fbuf .= shift while @_;
if ($ctx->{-heads}) {
while ($fbuf =~ s/\A([^\n]+)\n//s) {
- utf8::decode(my $x = $1);
+ utf8_maybe(my $x = $1);
push @out, _refs_heads_link($x, '../../');
}
} else {
my ($snap_pfx, @snap_fmt) = _snapshot_link_prep($ctx);
while ($fbuf =~ s/\A([^\n]+)\n//s) {
- utf8::decode(my $x = $1);
+ utf8_maybe(my $x = $1);
push @out, _refs_tags_link($x, '../../',
$snap_pfx, @snap_fmt);
}
'c2f3bf071ee90b01f2d629921bb04c4f798f02fa/s/', # tag
'7eb93c89651c47c8095d476251f2e4314656b292/s/', # non-UTF-8
],
+ 'sox-devel' => [
+ 'c38987e8d20505621b8d872863afa7d233ed1096/s/', # non-UTF-8
+ ]
};
-my ($ibx_name, $urls, @gone);
+my @gone;
my $client = sub {
my ($cb) = @_;
- for my $u (@$urls) {
- my $url = "/$ibx_name/$u";
- my $res = $cb->(GET($url));
- is($res->code, 200, $url);
- next if $res->code == 200;
- diag "$url failed";
- diag $res->content;
+ for my $ibx_name (sort keys %$todo) {
+ diag "testing $ibx_name";
+ my $urls = $todo->{$ibx_name};
+ for my $u (@$urls) {
+ my $url = "/$ibx_name/$u";
+ my $res = $cb->(GET($url));
+ is($res->code, 200, $url);
+ next if $res->code == 200;
+ diag "$url failed";
+ diag $res->content;
+ }
}
};
my $nr = 0;
-while (($ibx_name, $urls) = each %$todo) {
+while (my ($ibx_name, $urls) = each %$todo) {
SKIP: {
my $ibx = $cfg->lookup_name($ibx_name);
if (!$ibx) {
skip(qq{publicinbox.$ibx_name.coderepo not configured},
scalar(@$urls));
}
- test_psgi($app, $client);
$nr++;
}
}
delete @$todo{@gone};
+test_psgi($app, $client);
my $env = { PI_CONFIG => PublicInbox::Config->default_file };
-while (($ibx_name, $urls) = each %$todo) {
- test_httpd($env, $client, $nr);
-}
+test_httpd($env, $client, $nr);
done_testing();