@@ -1178,6 +1178,13 @@ sub esc_url {
11781178 return $str ;
11791179}
11801180
1181+ # quote unsafe characters in HTML attributes
1182+ sub esc_attr {
1183+
1184+ # for XHTML conformance escaping '"' to '"' is not enough
1185+ return esc_html(@_ );
1186+ }
1187+
11811188# replace invalid utf8 character with SUBSTITUTION sequence
11821189sub esc_html {
11831190 my $str = shift ;
@@ -1583,7 +1590,7 @@ sub format_ref_marker {
15831590 hash => $dest
15841591 )}, $name );
15851592
1586- $markers .= " <span class=\" $class \" title=\" $ref \" >" .
1593+ $markers .= " <span class=\" " .esc_attr( $class ). " \" title=\" " .esc_attr( $ref ). " \" >" .
15871594 $link . " </span>" ;
15881595 }
15891596 }
@@ -1667,7 +1674,7 @@ sub git_get_avatar {
16671674 return $pre_white .
16681675 " <img width=\" $size \" " .
16691676 " class=\" avatar\" " .
1670- " src=\" $url \" " .
1677+ " src=\" " .esc_url( $url ). " \" " .
16711678 " alt=\"\" " .
16721679 " />" . $post_white ;
16731680 } else {
@@ -2378,7 +2385,7 @@ sub git_show_project_tagcloud {
23782385 } else {
23792386 my @tags = sort { $cloud -> {$a }-> {count } <=> $cloud -> {$b }-> {count } } keys %$cloud ;
23802387 return ' <p align="center">' . join (' , ' , map {
2381- " <a href=\ "$home_link ?by_tag=$_ \" > $cloud ->{$_ }->{topname}</a> "
2388+ $cgi -> a({- href => " $home_link ?by_tag=$_ " }, $cloud -> {$_ }-> {topname })
23822389 } splice (@tags , 0, $count )) . ' </p>' ;
23832390 }
23842391}
@@ -3209,11 +3216,11 @@ sub git_header_html {
32093216 # print out each stylesheet that exist, providing backwards capability
32103217 # for those people who defined $stylesheet in a config file
32113218 if (defined $stylesheet ) {
3212- print ' <link rel="stylesheet" type="text/css" href="' .$stylesheet .' "/>' ." \n " ;
3219+ print ' <link rel="stylesheet" type="text/css" href="' .esc_url( $stylesheet ) .' "/>' ." \n " ;
32133220 } else {
32143221 foreach my $stylesheet (@stylesheets ) {
32153222 next unless $stylesheet ;
3216- print ' <link rel="stylesheet" type="text/css" href="' .$stylesheet .' "/>' ." \n " ;
3223+ print ' <link rel="stylesheet" type="text/css" href="' .esc_url( $stylesheet ) .' "/>' ." \n " ;
32173224 }
32183225 }
32193226 if (defined $project ) {
@@ -3226,7 +3233,7 @@ sub git_header_html {
32263233 my $type = lc ($format );
32273234 my %link_attr = (
32283235 ' -rel' => ' alternate' ,
3229- ' -title' => " $project - $href_params {'-title'} - $format feed" ,
3236+ ' -title' => esc_attr( " $project - $href_params {'-title'} - $format feed" ) ,
32303237 ' -type' => " application/$type +xml"
32313238 );
32323239
@@ -3253,13 +3260,13 @@ sub git_header_html {
32533260 } else {
32543261 printf (' <link rel="alternate" title="%s projects list" ' .
32553262 ' href="%s" type="text/plain; charset=utf-8" />' ." \n " ,
3256- $site_name , href(project => undef , action => " project_index" ));
3263+ esc_attr( $site_name ) , href(project => undef , action => " project_index" ));
32573264 printf (' <link rel="alternate" title="%s projects feeds" ' .
32583265 ' href="%s" type="text/x-opml" />' ." \n " ,
3259- $site_name , href(project => undef , action => " opml" ));
3266+ esc_attr( $site_name ) , href(project => undef , action => " opml" ));
32603267 }
32613268 if (defined $favicon ) {
3262- print qq( <link rel="shortcut icon" href="$favicon " type="image/png" />\n ) ;
3269+ print qq( <link rel="shortcut icon" href=") .esc_url( $favicon ). qq( " type="image/png" />\n ) ;
32633270 }
32643271
32653272 print " </head>\n " .
@@ -3272,7 +3279,7 @@ sub git_header_html {
32723279 print " <div class=\" page_header\" >\n " .
32733280 $cgi -> a({-href => esc_url($logo_url ),
32743281 -title => $logo_label },
3275- qq( <img src="$logo " width="72" height="27" alt="git" class="logo"/>) );
3282+ qq( <img src=") .esc_url( $logo ). qq( " width="72" height="27" alt="git" class="logo"/>) );
32763283 print $cgi -> a({-href => esc_url($home_link )}, $home_link_str ) . " / " ;
32773284 if (defined $project ) {
32783285 print $cgi -> a({-href => href(action => " summary" )}, esc_html($project ));
@@ -3370,7 +3377,7 @@ sub git_footer_html {
33703377 insert_file($site_footer );
33713378 }
33723379
3373- print qq! <script type="text/javascript" src="$javascript "></script>\n ! ;
3380+ print qq! <script type="text/javascript" src="! .esc_url( $javascript ). qq! "></script>\n ! ;
33743381 if (defined $action &&
33753382 $action eq ' blame_incremental' ) {
33763383 print qq! <script type="text/javascript">\n ! .
@@ -5382,14 +5389,14 @@ sub git_blob {
53825389 } else {
53835390 print " <div class=\" page_nav\" >\n " .
53845391 " <br/><br/></div>\n " .
5385- " <div class=\" title\" >$hash </div>\n " ;
5392+ " <div class=\" title\" >" .esc_html( $hash ). " </div>\n " ;
53865393 }
53875394 git_print_page_path($file_name , " blob" , $hash_base );
53885395 print " <div class=\" page_body\" >\n " ;
53895396 if ($mimetype =~ m ! ^image/! ) {
5390- print qq! <img type="$mimetype "! ;
5397+ print qq! <img type="! .esc_attr( $mimetype ). qq! "! ;
53915398 if ($file_name ) {
5392- print qq! alt="$file_name " title="$file_name "! ;
5399+ print qq! alt="! .esc_attr( $file_name ). qq! " title="! .esc_attr( $file_name ). qq! "! ;
53935400 }
53945401 print qq! src="! .
53955402 href(action => " blob_plain" , hash => $hash ,
@@ -5401,7 +5408,8 @@ sub git_blob {
54015408 chomp $line ;
54025409 $nr ++;
54035410 $line = untabify($line );
5404- printf " <div class=\" pre\" ><a id=\" l%i \" href=\" " . href(-replay => 1)
5411+ printf " <div class=\" pre\" ><a id=\" l%i \" href=\" "
5412+ . esc_attr(href(-replay => 1))
54055413 . " #l%i \" class=\" linenr\" >%4i</a> %s </div>\n " ,
54065414 $nr , $nr , $nr , esc_html($line , -nbsp => 1);
54075415 }
@@ -5465,7 +5473,7 @@ sub git_tree {
54655473 undef $hash_base ;
54665474 print " <div class=\" page_nav\" >\n " ;
54675475 print " <br/><br/></div>\n " ;
5468- print " <div class=\" title\" >$hash </div>\n " ;
5476+ print " <div class=\" title\" >" .esc_html( $hash ). " </div>\n " ;
54695477 }
54705478 if (defined $file_name ) {
54715479 $basedir = $file_name ;
@@ -5933,7 +5941,7 @@ sub git_blobdiff {
59335941 git_print_header_div(' commit' , esc_html($co {' title' }), $hash_base );
59345942 } else {
59355943 print " <div class=\" page_nav\" ><br/>$formats_nav <br/></div>\n " ;
5936- print " <div class=\" title\" >$hash vs $hash_parent </div>\n " ;
5944+ print " <div class=\" title\" >" .esc_html( " $hash vs $hash_parent " ). " </div>\n " ;
59375945 }
59385946 if (defined $file_name ) {
59395947 git_print_page_path($file_name , " blob" , $hash_base );
0 commit comments