94
94
# (relative to the current git repository)
95
95
our $mimetypes_file = undef ;
96
96
97
+ # assume this charset if line contains non-UTF-8 characters;
98
+ # it should be valid encoding (see Encoding::Supported(3pm) for list),
99
+ # for which encoding all byte sequences are valid, for example
100
+ # 'iso-8859-1' aka 'latin1' (it is decoded without checking, so it
101
+ # could be even 'utf-8' for the old behavior)
102
+ our $fallback_encoding = ' latin1' ;
103
+
97
104
# You define site-wide feature defaults here; override them with
98
105
# $GITWEB_CONFIG as necessary.
99
106
our %feature = (
@@ -602,6 +609,20 @@ sub validate_refname {
602
609
return $input ;
603
610
}
604
611
612
+ # decode sequences of octets in utf8 into Perl's internal form,
613
+ # which is utf-8 with utf8 flag set if needed. gitweb writes out
614
+ # in utf-8 thanks to "binmode STDOUT, ':utf8'" at beginning
615
+ sub to_utf8 {
616
+ my $str = shift ;
617
+ my $res ;
618
+ eval { $res = decode_utf8($str , Encode::FB_CROAK); };
619
+ if (defined $res ) {
620
+ return $res ;
621
+ } else {
622
+ return decode($fallback_encoding , $str , Encode::FB_DEFAULT);
623
+ }
624
+ }
625
+
605
626
# quote unsafe chars, but keep the slash, even when it's not
606
627
# correct, but quoted slashes look too horrible in bookmarks
607
628
sub esc_param {
@@ -626,7 +647,7 @@ ($;%)
626
647
my $str = shift ;
627
648
my %opts = @_ ;
628
649
629
- $str = decode_utf8 ($str );
650
+ $str = to_utf8 ($str );
630
651
$str = $cgi -> escapeHTML($str );
631
652
if ($opts {' -nbsp' }) {
632
653
$str =~ s / / / g ;
@@ -640,7 +661,7 @@ sub esc_path {
640
661
my $str = shift ;
641
662
my %opts = @_ ;
642
663
643
- $str = decode_utf8 ($str );
664
+ $str = to_utf8 ($str );
644
665
$str = $cgi -> escapeHTML($str );
645
666
if ($opts {' -nbsp' }) {
646
667
$str =~ s / / / g ;
@@ -925,7 +946,7 @@ sub format_subject_html {
925
946
926
947
if (length ($short ) < length ($long )) {
927
948
return $cgi -> a({-href => $href , -class => " list subject" ,
928
- -title => decode_utf8 ($long )},
949
+ -title => to_utf8 ($long )},
929
950
esc_html($short ) . $extra );
930
951
} else {
931
952
return $cgi -> a({-href => $href , -class => " list subject" },
@@ -1239,7 +1260,7 @@ sub git_get_projects_list {
1239
1260
if (check_export_ok(" $projectroot /$path " )) {
1240
1261
my $pr = {
1241
1262
path => $path ,
1242
- owner => decode_utf8 ($owner ),
1263
+ owner => to_utf8 ($owner ),
1243
1264
};
1244
1265
push @list , $pr ;
1245
1266
(my $forks_path = $path ) =~ s /\. git$// ;
@@ -1269,7 +1290,7 @@ sub git_get_project_owner {
1269
1290
$pr = unescape($pr );
1270
1291
$ow = unescape($ow );
1271
1292
if ($pr eq $project ) {
1272
- $owner = decode_utf8 ($ow );
1293
+ $owner = to_utf8 ($ow );
1273
1294
last ;
1274
1295
}
1275
1296
}
@@ -1759,7 +1780,7 @@ sub get_file_owner {
1759
1780
}
1760
1781
my $owner = $gcos ;
1761
1782
$owner =~ s / [,;].*$// ;
1762
- return decode_utf8 ($owner );
1783
+ return to_utf8 ($owner );
1763
1784
}
1764
1785
1765
1786
# # ......................................................................
@@ -1842,7 +1863,7 @@ sub git_header_html {
1842
1863
1843
1864
my $title = " $site_name " ;
1844
1865
if (defined $project ) {
1845
- $title .= " - " . decode_utf8 ($project );
1866
+ $title .= " - " . to_utf8 ($project );
1846
1867
if (defined $action ) {
1847
1868
$title .= " /$action " ;
1848
1869
if (defined $file_name ) {
@@ -2116,7 +2137,7 @@ sub git_print_page_path {
2116
2137
2117
2138
print " <div class=\" page_path\" >" ;
2118
2139
print $cgi -> a({-href => href(action => " tree" , hash_base => $hb ),
2119
- -title => ' tree root' }, decode_utf8 (" [$project ]" ));
2140
+ -title => ' tree root' }, to_utf8 (" [$project ]" ));
2120
2141
print " / " ;
2121
2142
if (defined $name ) {
2122
2143
my @dirname = split ' /' , $name ;
@@ -2936,7 +2957,7 @@ sub git_project_list_body {
2936
2957
($pr -> {' age' }, $pr -> {' age_string' }) = @aa ;
2937
2958
if (!defined $pr -> {' descr' }) {
2938
2959
my $descr = git_get_project_description($pr -> {' path' }) || " " ;
2939
- $pr -> {' descr_long' } = decode_utf8 ($descr );
2960
+ $pr -> {' descr_long' } = to_utf8 ($descr );
2940
2961
$pr -> {' descr' } = chop_str($descr , 25, 5);
2941
2962
}
2942
2963
if (!defined $pr -> {' owner' }) {
@@ -3981,7 +4002,7 @@ sub git_snapshot {
3981
4002
my $git = git_cmd_str();
3982
4003
my $name = $project ;
3983
4004
$name =~ s /\047 / \047\\\047\047 / g ;
3984
- my $filename = decode_utf8 (basename($project ));
4005
+ my $filename = to_utf8 (basename($project ));
3985
4006
my $cmd ;
3986
4007
if ($suffix eq ' zip' ) {
3987
4008
$filename .= " -$hash .$suffix " ;
0 commit comments