From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Subject: [PATCH (bugfix)] gitweb: Add and use prep_attr helper
Date: Wed, 15 Sep 2010 22:34:12 +0200 [thread overview]
Message-ID: <201009152234.14253.jnareb@gmail.com> (raw)
One of features of CGI.pm module is HTML generation. The HTML
generation subroutines / methods automatically escape values of
attributes of HTML elements... but in older versions didn't do it
fully, not removing / replacing control characters. Control
characters are forbidden in XML / XHTML, and some browsers
(e.g. Firefox) do not skip over them but display error instead of page
in strict XHTML mode (XHTML DTD + application/xml+html mimetype).
This issue was noticed by Uwe Kleine-König and resolved to be a
problem with control characters in XHTML output by Ævar Arnfjörð
Bjarmason in format_search_author() subroutine.
Introduce prep_attr subroutine to deal with this problem, and use it
in all places where we use data from outside gitweb in attributes of
HTML elements, where those HTML elements are generated by CGI.pm
subroutines / methods (this usually means 'title' attribute).
While at it simplify format_search_author() a bit, and use spaces
for align.
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This is a more generic replacement for
[PATCH] gitweb: Harden format_search_author()
http://thread.gmane.org/gmane.comp.version-control.git/152379/focus=152543
from 2010-08-03
gitweb/gitweb.perl | 62 +++++++++++++++++++++++++++++++---------------------
1 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a85e2f6..da20209 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1346,6 +1346,22 @@ sub esc_param {
return $str;
}
+# prepare 'attribute => value' pair for CGI.pm HTML generation,
+# by escaping/quoting/replacing/removing values which are invalid in (X)HTML,
+# and which older versions of CGI.pm do not quote correctly
+#
+# USAGE:
+# $cgi->a({-href => ..., prep_attr(-title => $title)}, esc_html($contents));
+# $cgi->a({-href => ..., -title => prep_attr($title)}, esc_html($contents));
+sub prep_attr {
+ my ($attr_name, $value) = @_ > 1 ? @_ : (undef, @_);
+
+ $value = to_utf8($value);
+ $value =~ s/[[:cntrl:]]/?/g;
+
+ return defined $attr_name ? ($attr_name => $value) : $value;
+}
+
# quote unsafe chars in whole URL, so some characters cannot be quoted
sub esc_url {
my $str = shift;
@@ -1555,8 +1571,7 @@ sub chop_and_escape_str {
if ($chopped eq $str) {
return esc_html($chopped);
} else {
- $str =~ s/[[:cntrl:]]/?/g;
- return $cgi->span({-title=>$str}, esc_html($chopped));
+ return $cgi->span({prep_attr(-title=>$str)}, esc_html($chopped));
}
}
@@ -1778,9 +1793,8 @@ sub format_subject_html {
$extra = '' unless defined($extra);
if (length($short) < length($long)) {
- $long =~ s/[[:cntrl:]]/?/g;
return $cgi->a({-href => $href, -class => "list subject",
- -title => to_utf8($long)},
+ prep_attr(-title => $long)},
esc_html($short)) . $extra;
} else {
return $cgi->a({-href => $href, -class => "list subject"},
@@ -1856,23 +1870,20 @@ sub format_search_author {
my ($author, $searchtype, $displaytext) = @_;
my $have_search = gitweb_check_feature('search');
- if ($have_search) {
- my $performed = "";
- if ($searchtype eq 'author') {
- $performed = "authored";
- } elsif ($searchtype eq 'committer') {
- $performed = "committed";
- }
-
- return $cgi->a({-href => href(action=>"search", hash=>$hash,
- searchtext=>$author,
- searchtype=>$searchtype), class=>"list",
- title=>"Search for commits $performed by $author"},
- $displaytext);
+ return $displaytext unless ($have_search);
- } else {
- return $displaytext;
+ my $performed = "";
+ if ($searchtype eq 'author') {
+ $performed = "authored";
+ } elsif ($searchtype eq 'committer') {
+ $performed = "committed";
}
+
+ my $title = "Search for commits $performed by $author";
+ return $cgi->a({-href => href(action=>"search", hash=>$hash,
+ searchtext=>$author, searchtype=>$searchtype),
+ -class=>"list", prep_attr(-title=>$title)},
+ $displaytext);
}
# format the author name of the given commit with the given tag
@@ -3559,7 +3570,7 @@ sub git_footer_html {
foreach my $format qw(RSS Atom) {
$href_params{'action'} = lc($format);
print $cgi->a({-href => href(%href_params),
- -title => "$href_params{'-title'} $format feed",
+ prep_attr(-title => "$href_params{'-title'} $format feed"),
-class => $feed_class}, $format)."\n";
}
@@ -3827,17 +3838,17 @@ sub git_print_page_path {
$fullname .= ($fullname ? '/' : '') . $dir;
print $cgi->a({-href => href(action=>"tree", file_name=>$fullname,
hash_base=>$hb),
- -title => $fullname}, esc_path($dir));
+ prep_attr(-title => $fullname)}, esc_path($dir));
print " / ";
}
if (defined $type && $type eq 'blob') {
print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name,
hash_base=>$hb),
- -title => $name}, esc_path($basename));
+ prep_attr(-title => $name)}, esc_path($basename));
} elsif (defined $type && $type eq 'tree') {
print $cgi->a({-href => href(action=>"tree", file_name=>$file_name,
hash_base=>$hb),
- -title => $name}, esc_path($basename));
+ prep_attr(-title => $name)}, esc_path($basename));
print " / ";
} else {
print esc_path($basename);
@@ -3981,7 +3992,8 @@ sub git_print_tree_entry {
print " -> " .
$cgi->a({-href => href(action=>"object", hash_base=>$hash_base,
file_name=>$norm_target),
- -title => $norm_target}, esc_path($link_target));
+ prep_attr(-title => $norm_target)},
+ esc_path($link_target));
} else {
print " -> " . esc_path($link_target);
}
@@ -4687,7 +4699,7 @@ sub git_project_list_body {
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
- -class => "list", -title => $pr->{'descr_long'}},
+ -class => "list", prep_attr(-title => $pr->{'descr_long'})},
esc_html($pr->{'descr'})) . "</td>\n" .
"<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
--
1.7.2.1
next reply other threads:[~2010-09-15 20:37 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-15 20:34 Jakub Narebski [this message]
2010-09-15 20:40 ` [PATCH (bugfix)] gitweb: Add and use prep_attr helper Ævar Arnfjörð Bjarmason
2010-09-15 20:53 ` Junio C Hamano
2010-09-15 21:16 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201009152234.14253.jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=u.kleine-koenig@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 NNTP newsgroup(s).