@@ -760,6 +760,7 @@ sub check_loadavg {
760760 search_use_regexp => " sr" ,
761761 ctag => " by_tag" ,
762762 diff_style => " ds" ,
763+ project_filter => " pf" ,
763764 # this must be last entry (for manipulation from JavaScript)
764765 javascript => " js"
765766);
@@ -976,7 +977,7 @@ sub evaluate_path_info {
976977
977978our ($action , $project , $file_name , $file_parent , $hash , $hash_parent , $hash_base ,
978979 $hash_parent_base , @extra_options , $page , $searchtype , $search_use_regexp ,
979- $searchtext , $search_regexp );
980+ $searchtext , $search_regexp , $project_filter );
980981sub evaluate_and_validate_params {
981982 our $action = $input_params {' action' };
982983 if (defined $action ) {
@@ -994,6 +995,13 @@ sub evaluate_and_validate_params {
994995 }
995996 }
996997
998+ our $project_filter = $input_params {' project_filter' };
999+ if (defined $project_filter ) {
1000+ if (!validate_pathname($project_filter )) {
1001+ die_error(404, " Invalid project_filter parameter" );
1002+ }
1003+ }
1004+
9971005 our $file_name = $input_params {' file_name' };
9981006 if (defined $file_name ) {
9991007 if (!validate_pathname($file_name )) {
@@ -2829,10 +2837,9 @@ sub git_get_project_url_list {
28292837
28302838sub git_get_projects_list {
28312839 my $filter = shift || ' ' ;
2840+ my $paranoid = shift ;
28322841 my @list ;
28332842
2834- $filter =~ s /\. git$// ;
2835-
28362843 if (-d $projects_list ) {
28372844 # search in directory
28382845 my $dir = $projects_list ;
@@ -2841,7 +2848,7 @@ sub git_get_projects_list {
28412848 my $pfxlen = length (" $dir " );
28422849 my $pfxdepth = ($dir =~ tr ! /!! );
28432850 # when filtering, search only given subdirectory
2844- if ($filter ) {
2851+ if ($filter && ! $paranoid ) {
28452852 $dir .= " /$filter " ;
28462853 $dir =~ s ! /+$!! ;
28472854 }
@@ -2866,6 +2873,10 @@ sub git_get_projects_list {
28662873 }
28672874
28682875 my $path = substr ($File::Find::name , $pfxlen + 1);
2876+ # paranoidly only filter here
2877+ if ($paranoid && $filter && $path !~ m ! ^\Q $filter \E /! ) {
2878+ next ;
2879+ }
28692880 # we check related file in $projectroot
28702881 if (check_export_ok(" $projectroot /$path " )) {
28712882 push @list , { path => $path };
@@ -3731,7 +3742,12 @@ sub run_highlighter {
37313742sub get_page_title {
37323743 my $title = to_utf8($site_name );
37333744
3734- return $title unless (defined $project );
3745+ unless (defined $project ) {
3746+ if (defined $project_filter ) {
3747+ $title .= " - " . to_utf8($project_filter );
3748+ }
3749+ return $title ;
3750+ }
37353751 $title .= " - " . to_utf8($project );
37363752
37373753 return $title unless (defined $action );
@@ -3825,12 +3841,27 @@ sub print_header_links {
38253841 }
38263842}
38273843
3844+ sub print_nav_breadcrumbs_path {
3845+ my $dirprefix = undef ;
3846+ while (my $part = shift ) {
3847+ $dirprefix .= " /" if defined $dirprefix ;
3848+ $dirprefix .= $part ;
3849+ print $cgi -> a({-href => href(project => undef ,
3850+ project_filter => $dirprefix ,
3851+ action => " project_list" )},
3852+ esc_html($part )) . " / " ;
3853+ }
3854+ }
3855+
38283856sub print_nav_breadcrumbs {
38293857 my %opts = @_ ;
38303858
38313859 print $cgi -> a({-href => esc_url($home_link )}, $home_link_str ) . " / " ;
38323860 if (defined $project ) {
3833- print $cgi -> a({-href => href(action => " summary" )}, esc_html($project ));
3861+ my @dirname = split ' /' , $project ;
3862+ my $projectbasename = pop @dirname ;
3863+ print_nav_breadcrumbs_path(@dirname );
3864+ print $cgi -> a({-href => href(action => " summary" )}, esc_html($projectbasename ));
38343865 if (defined $action ) {
38353866 my $action_print = $action ;
38363867 if (defined $opts {-action_extra}) {
@@ -3843,6 +3874,8 @@ sub print_nav_breadcrumbs {
38433874 print " / $opts {-action_extra}" ;
38443875 }
38453876 print " \n " ;
3877+ } elsif (defined $project_filter ) {
3878+ print_nav_breadcrumbs_path(split ' /' , $project_filter );
38463879 }
38473880}
38483881
@@ -3965,9 +3998,11 @@ sub git_footer_html {
39653998 }
39663999
39674000 } else {
3968- print $cgi -> a({-href => href(project => undef , action => " opml" ),
4001+ print $cgi -> a({-href => href(project => undef , action => " opml" ,
4002+ project_filter => $project_filter ),
39694003 -class => $feed_class }, " OPML" ) . " " ;
3970- print $cgi -> a({-href => href(project => undef , action => " project_index" ),
4004+ print $cgi -> a({-href => href(project => undef , action => " project_index" ,
4005+ project_filter => $project_filter ),
39714006 -class => $feed_class }, " TXT" ) . " \n " ;
39724007 }
39734008 print " </div>\n " ; # class="page_footer"
@@ -5125,6 +5160,34 @@ sub git_patchset_body {
51255160
51265161# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51275162
5163+ sub git_project_search_form {
5164+ my ($searchtext , $search_use_regexp );
5165+
5166+ my $limit = ' ' ;
5167+ if ($project_filter ) {
5168+ $limit = " in '$project_filter /'" ;
5169+ }
5170+
5171+ print " <div class=\" projsearch\" >\n " ;
5172+ print $cgi -> startform(-method => ' get' , -action => $my_uri ) .
5173+ $cgi -> hidden(-name => ' a' , -value => ' project_list' ) . " \n " ;
5174+ print $cgi -> hidden(-name => ' pf' , -value => $project_filter ). " \n "
5175+ if (defined $project_filter );
5176+ print $cgi -> textfield(-name => ' s' , -value => $searchtext ,
5177+ -title => " Search project by name and description$limit " ,
5178+ -size => 60) . " \n " .
5179+ " <span title=\" Extended regular expression\" >" .
5180+ $cgi -> checkbox(-name => ' sr' , -value => 1, -label => ' re' ,
5181+ -checked => $search_use_regexp ) .
5182+ " </span>\n " .
5183+ $cgi -> submit(-name => ' btnS' , -value => ' Search' ) .
5184+ $cgi -> end_form() . " \n " .
5185+ $cgi -> a({-href => href(project => undef , searchtext => undef ,
5186+ project_filter => $project_filter )},
5187+ esc_html(" List all projects$limit " )) . " <br />\n " ;
5188+ print " </div>\n " ;
5189+ }
5190+
51285191# fills project list info (age, description, owner, category, forks)
51295192# for each project in the list, removing invalid projects from
51305193# returned list
@@ -5981,7 +6044,7 @@ sub git_project_list {
59816044 die_error(400, " Unknown order parameter" );
59826045 }
59836046
5984- my @list = git_get_projects_list();
6047+ my @list = git_get_projects_list($project_filter , $strict_export );
59856048 if (!@list ) {
59866049 die_error(404, " No projects found" );
59876050 }
@@ -5992,11 +6055,8 @@ sub git_project_list {
59926055 insert_file($home_text );
59936056 print " </div>\n " ;
59946057 }
5995- print $cgi -> startform(-method => " get" ) .
5996- " <p class=\" projsearch\" >Search:\n " .
5997- $cgi -> textfield(-name => " s" , -value => $searchtext ) . " \n " .
5998- " </p>" .
5999- $cgi -> end_form() . " \n " ;
6058+
6059+ git_project_search_form($searchtext , $search_use_regexp );
60006060 git_project_list_body(\@list , $order );
60016061 git_footer_html();
60026062}
@@ -6007,7 +6067,9 @@ sub git_forks {
60076067 die_error(400, " Unknown order parameter" );
60086068 }
60096069
6010- my @list = git_get_projects_list($project );
6070+ my $filter = $project ;
6071+ $filter =~ s /\. git$// ;
6072+ my @list = git_get_projects_list($filter );
60116073 if (!@list ) {
60126074 die_error(404, " No forks found" );
60136075 }
@@ -6020,7 +6082,7 @@ sub git_forks {
60206082}
60216083
60226084sub git_project_index {
6023- my @projects = git_get_projects_list();
6085+ my @projects = git_get_projects_list($project_filter , $strict_export );
60246086 if (!@projects ) {
60256087 die_error(404, " No projects found" );
60266088 }
@@ -6066,7 +6128,9 @@ sub git_summary {
60666128
60676129 if ($check_forks ) {
60686130 # find forks of a project
6069- @forklist = git_get_projects_list($project );
6131+ my $filter = $project ;
6132+ $filter =~ s /\. git$// ;
6133+ @forklist = git_get_projects_list($filter );
60706134 # filter out forks of forks
60716135 @forklist = filter_forks_from_projects_list(\@forklist )
60726136 if (@forklist );
@@ -7857,7 +7921,7 @@ sub git_atom {
78577921}
78587922
78597923sub git_opml {
7860- my @list = git_get_projects_list();
7924+ my @list = git_get_projects_list($project_filter , $strict_export );
78617925 if (!@list ) {
78627926 die_error(404, " No projects found" );
78637927 }
@@ -7868,11 +7932,17 @@ sub git_opml {
78687932 -content_disposition => ' inline; filename="opml.xml"' );
78697933
78707934 my $title = esc_html($site_name );
7935+ my $filter = " within subdirectory " ;
7936+ if (defined $project_filter ) {
7937+ $filter .= esc_html($project_filter );
7938+ } else {
7939+ $filter = " " ;
7940+ }
78717941 print <<XML ;
78727942<?xml version =" 1.0" encoding =" utf-8" ?>
78737943<opml version =" 1.0" >
78747944<head >
7875- <title >$title OPML Export</title >
7945+ <title >$title OPML Export$filter </title >
78767946</head >
78777947<body >
78787948<outline text =" git RSS feeds" >
0 commit comments