Skip to content

Commit 643b6ef

Browse files
committed
Merge branch 'jn/maint-gitweb-pathinfo-fix'
* jn/maint-gitweb-pathinfo-fix: gitweb: Fix handling of whitespace in generated links
2 parents 00b0d7f + 67976c6 commit 643b6ef

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

gitweb/gitweb.perl

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,7 +1230,7 @@ sub href {
12301230
$href =~ s,/$,,;
12311231

12321232
# Then add the project name, if present
1233-
$href .= "/".esc_url($params{'project'});
1233+
$href .= "/".esc_path_info($params{'project'});
12341234
delete $params{'project'};
12351235

12361236
# since we destructively absorb parameters, we keep this
@@ -1240,7 +1240,8 @@ sub href {
12401240
# Summary just uses the project path URL, any other action is
12411241
# added to the URL
12421242
if (defined $params{'action'}) {
1243-
$href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary';
1243+
$href .= "/".esc_path_info($params{'action'})
1244+
unless $params{'action'} eq 'summary';
12441245
delete $params{'action'};
12451246
}
12461247

@@ -1250,33 +1251,33 @@ sub href {
12501251
|| $params{'hash_parent'} || $params{'hash'});
12511252
if (defined $params{'hash_base'}) {
12521253
if (defined $params{'hash_parent_base'}) {
1253-
$href .= esc_url($params{'hash_parent_base'});
1254+
$href .= esc_path_info($params{'hash_parent_base'});
12541255
# skip the file_parent if it's the same as the file_name
12551256
if (defined $params{'file_parent'}) {
12561257
if (defined $params{'file_name'} && $params{'file_parent'} eq $params{'file_name'}) {
12571258
delete $params{'file_parent'};
12581259
} elsif ($params{'file_parent'} !~ /\.\./) {
1259-
$href .= ":/".esc_url($params{'file_parent'});
1260+
$href .= ":/".esc_path_info($params{'file_parent'});
12601261
delete $params{'file_parent'};
12611262
}
12621263
}
12631264
$href .= "..";
12641265
delete $params{'hash_parent'};
12651266
delete $params{'hash_parent_base'};
12661267
} elsif (defined $params{'hash_parent'}) {
1267-
$href .= esc_url($params{'hash_parent'}). "..";
1268+
$href .= esc_path_info($params{'hash_parent'}). "..";
12681269
delete $params{'hash_parent'};
12691270
}
12701271

1271-
$href .= esc_url($params{'hash_base'});
1272+
$href .= esc_path_info($params{'hash_base'});
12721273
if (defined $params{'file_name'} && $params{'file_name'} !~ /\.\./) {
1273-
$href .= ":/".esc_url($params{'file_name'});
1274+
$href .= ":/".esc_path_info($params{'file_name'});
12741275
delete $params{'file_name'};
12751276
}
12761277
delete $params{'hash'};
12771278
delete $params{'hash_base'};
12781279
} elsif (defined $params{'hash'}) {
1279-
$href .= esc_url($params{'hash'});
1280+
$href .= esc_path_info($params{'hash'});
12801281
delete $params{'hash'};
12811282
}
12821283

@@ -1309,6 +1310,9 @@ sub href {
13091310
}
13101311
$href .= "?" . join(';', @result) if scalar @result;
13111312

1313+
# final transformation: trailing spaces must be escaped (URI-encoded)
1314+
$href =~ s/(\s+)$/CGI::escape($1)/e;
1315+
13121316
return $href;
13131317
}
13141318

@@ -1391,6 +1395,17 @@ sub esc_param {
13911395
return $str;
13921396
}
13931397

1398+
# the quoting rules for path_info fragment are slightly different
1399+
sub esc_path_info {
1400+
my $str = shift;
1401+
return undef unless defined $str;
1402+
1403+
# path_info doesn't treat '+' as space (specially), but '?' must be escaped
1404+
$str =~ s/([^A-Za-z0-9\-_.~();\/;:@&= +]+)/CGI::escape($1)/eg;
1405+
1406+
return $str;
1407+
}
1408+
13941409
# quote unsafe chars in whole URL, so some characters cannot be quoted
13951410
sub esc_url {
13961411
my $str = shift;

0 commit comments

Comments
 (0)