]> git.donarmstrong.com Git - debbugs.git/commitdiff
merge changes from dla source tree
authorDebian BTS <debbugs@rietz>
Tue, 26 Jun 2007 18:13:58 +0000 (18:13 +0000)
committerDebian BTS <debbugs@rietz>
Tue, 26 Jun 2007 18:13:58 +0000 (18:13 +0000)
Debbugs/Bugs.pm
Debbugs/SOAP.pm
cgi/common.pl
cgi/pkgindex.cgi
cgi/pkgreport.cgi

index 9879e3fd1a8f7f34d50d75657d23fd254b608319..848931f79b8fcca9799324a814630ee2d77666a8 100644 (file)
@@ -46,18 +46,20 @@ BEGIN{
 
      @EXPORT = ();
      %EXPORT_TAGS = ();
-     @EXPORT_OK = (qw(get_bugs count_bugs newest_bug));
+     @EXPORT_OK = (qw(get_bugs count_bugs newest_bug bug_filter));
      $EXPORT_TAGS{all} = [@EXPORT_OK];
 }
 
 use Debbugs::Config qw(:config);
 use Params::Validate qw(validate_with :types);
 use IO::File;
-use Debbugs::Status qw(splitpackages);
+use Debbugs::Status qw(splitpackages get_bug_status);
 use Debbugs::Packages qw(getsrcpkgs);
 use Debbugs::Common qw(getparsedaddrs getmaintainers getmaintainers_reverse make_list);
 use Fcntl qw(O_RDONLY);
 use MLDBM qw(DB_File Storable);
+use List::Util qw(first);
+use Carp;
 
 =head2 get_bugs
 
@@ -291,6 +293,77 @@ sub newest_bug {
      return $next_number+0;
 }
 
+=head2 bug_filter
+
+     bug_filter
+
+Allows filtering bugs on commonly used criteria
+
+=cut
+
+sub bug_filter {
+     my %param = validate_with(params => \@_,
+                              spec   => {bug => {type  => SCALAR,
+                                                 regex => qr/^\d+$/,
+                                                },
+                                         status => {type => HASHREF,
+                                                    optional => 1,
+                                                   },
+                                         seen_merged => {type => HASHREF,
+                                                         optional => 1,
+                                                        },
+                                         repeat_merged => {type => BOOLEAN,
+                                                           optional => 1,
+                                                          },
+                                         include => {type => HASHREF,
+                                                     optional => 1,
+                                                    },
+                                         exclude => {type => HASHREF,
+                                                     optional => 1,
+                                                    },
+                                         min_days => {type => SCALAR,
+                                                      optional => 1,
+                                                     },
+                                         max_days => {type => SCALAR,
+                                                      optional => 1,
+                                                     },
+                                        },
+                             );
+     if (exists $param{repeat_merged} and
+        not $param{repeat_merged} and
+        not defined $param{seen_merged}) {
+         croak "repeat_merged false requires seen_merged to be passed";
+     }
+
+     if (not exists $param{status}) {
+         my $location = getbuglocation($param{bug}, 'summary');
+         return 0 if not defined $location or not length $location;
+         $param{status} = readbug( $param{bug}, $location );
+         return 0 if not defined $param{status};
+     }
+
+     if (exists $param{include}) {
+         return 1 if (!__bug_matches($param{include}, $param{status}));
+     }
+     if (exists $param{exclude}) {
+         return 1 if (__bug_matches($param{exclude}, $param{status}));
+     }
+     if (exists $param{repeat_merged} and not $param{repeat_merged}) {
+         my @merged = sort {$a<=>$b} $param{bug}, split(/ /, $param{status}{mergedwith});
+         return 1 if first {defined $_} @{$param{seen_merged}}{@merged};
+         @{$param{seen_merged}}{@merged} = (1) x @merged;
+     }
+     my $daysold = int((time - $param{status}{date}) / 86400);   # seconds to days
+     if (exists $param{min_days}) {
+         return 1 unless $param{min_days} <= $daysold;
+     }
+     if (exists $param{max_days}) {
+         return 1 unless $param{max_days} == -1 or
+              $param{max_days} >= $daysold;
+     }
+     return 0;
+}
+
 
 =head2 get_bugs_by_idx
 
@@ -530,6 +603,18 @@ sub get_bugs_flatfile{
      return @bugs;
 }
 
+=head1 PRIVATE FUNCTIONS
+
+=head2 __handle_pkg_src_and_maint
+
+     my @packages = __handle_pkg_src_and_maint(map {exists $param{$_}?($_,$param{$_}):()}
+                                              qw(package src maint)
+                                             );
+
+Turn package/src/maint into a list of packages
+
+=cut
+
 sub __handle_pkg_src_and_maint{
      my %param = validate_with(params => \@_,
                               spec   => {package   => {type => SCALAR|ARRAYREF,
@@ -573,6 +658,51 @@ sub __handle_pkg_src_and_maint{
      return grep {$packages{$_} >= $package_keys} keys %packages;
 }
 
+my %field_match = (
+    'subject' => \&__contains_field_match,
+    'tags' => sub {
+        my ($field, $values, $status) = @_; 
+       my %values = map {$_=>1} @$values;
+       foreach my $t (split /\s+/, $status->{$field}) {
+            return 1 if (defined $values{$t});
+        }
+        return 0;
+    },
+    'severity' => \&__exact_field_match,
+    'pending' => \&__exact_field_match,
+    'originator' => \&__contains_field_match,
+    'forwarded' => \&__contains_field_match,
+    'owner' => \&__contains_field_match,
+);
+
+sub __bug_matches {
+    my ($hash, $status) = @_;
+    foreach my $key( keys( %$hash ) ) {
+        my $value = $hash->{$key};
+       my $sub = $field_match{$key};
+       return 1 if ($sub->($key, $value, $status));
+    }
+    return 0;
+}
+
+sub __exact_field_match {
+    my ($field, $values, $status) = @_; 
+    my @values = @$values;
+    my @ret = grep {$_ eq $status->{$field} } @values;
+    $#ret != -1;
+}
+
+sub __contains_field_match {
+    my ($field, $values, $status) = @_; 
+    foreach my $data (@$values) {
+        return 1 if (index($status->{$field}, $data) > -1);
+    }
+    return 0;
+}
+
+
+
+
 
 1;
 
index fc6af2ec9e93a343fd4ba4214f2b8155702318dc..cfe74bbf0c43cc4c5d63f7bd406b139cb6e9cab4 100644 (file)
@@ -109,6 +109,8 @@ sub get_status {
 
      my @bugs = get_bugs(...);
 
+Returns a list of bugs.
+
 See L<Debbugs::Bugs::get_bugs> for details.
 
 =cut
@@ -182,9 +184,7 @@ sub get_bug_log{
      my @messages;
      while (my $record = $log->read_record()) {
          $current_msg++;
-         print STDERR "message $current_msg\n";
          #next if defined $msg_num and ($current_msg ne $msg_num);
-         print STDERR "still message $current_msg\n";
          next unless $record->{type} eq 'incoming-recv';
          my ($msg_id) = $record->{text} =~ /^Message-Id:\s+<(.+)>/im;
          next if defined $msg_id and exists $seen_msg_ids{$msg_id};
@@ -193,7 +193,6 @@ sub get_bug_log{
          my $message = parse($record->{text});
          my ($header,$body) = map {join("\n",make_list($_))}
               values %{$message};
-         print STDERR "still still message $current_msg\n";
          push @messages,{html => $record->{html},
                          header => $header,
                          body   => $body,
index 4701006e378dbe7de0b5ec02c54806a11ba3b7b4..05b8941ac7f84f8a2d2e07b9556ba9c6cabf577c 100644 (file)
@@ -454,7 +454,7 @@ sub allbugs {
     return @{getbugs(sub { 1 })};
 }
 
-sub bugmatches(\%\%) {
+sub bugmatches {
     my ($hash, $status) = @_;
     foreach my $key( keys( %$hash ) ) {
         my $value = $hash->{$key};
@@ -463,14 +463,14 @@ sub bugmatches(\%\%) {
     }
     return 0;
 }
-sub bugfilter($%) {
-    my ($bug, %status) = @_;
-    our (%seenmerged);
-    if (%common_include) {
-       return 1 if (!bugmatches(%common_include, %status));
-    }
-    if (%common_exclude) {
-       return 1 if (bugmatches(%common_exclude, %status));
+sub bugfilter {
+    my ($bug, $status,$seen_merged,$common_include,$common_exclude,$repeat_merged,) = @_;
+    #our (%seenmerged);
+    if ($common_include) {
+       return 1 if (!bugmatches($common_include, $status));
+    }
+    if ($common_exclude) {
+       return 1 if (bugmatches($common_exclude, $status));
     }
     my @merged = sort {$a<=>$b} $bug, split(/ /, $status{mergedwith});
     my $daysold = int((time - $status{date}) / 86400);   # seconds to days
index c667aacab0e2d11905e2a9cd81b45f28347479ff..8adbfb86c18714eba413c515d1dd387b2acad717 100755 (executable)
@@ -6,8 +6,10 @@ use POSIX qw(strftime nice);
 
 use Debbugs::Config;
 use CGI::Simple;
-use Debbugs::CGI qw(cgi_parameters);
-require './common.pl';
+use Debbugs::CGI qw(:util :url :html);
+use Debbugs::Common qw(getmaintainers);
+use Debbugs::Bugs qw(count_bugs);
+use Debbugs::Status qw(:status);
 
 nice(5);
 
@@ -66,7 +68,7 @@ my %htmldescrip = ();
 my %sortkey = ();
 if ($indexon eq "pkg") {
   $tag = "package";
-  %count = countbugs(sub {my %d=@_; return splitpackages($d{"pkg"})});
+  %count = count_bugs(function => sub {my %d=@_; return splitpackages($d{"pkg"})});
   if (defined $param{first}) {
        %count = map {
            if (/^\Q$param{first}\E/) {
@@ -82,9 +84,9 @@ if ($indexon eq "pkg") {
   foreach my $pkg (keys %count) {
     $sortkey{$pkg} = lc $pkg;
     $htmldescrip{$pkg} = sprintf('<a href="%s">%s</a> (%s)',
-                           pkgurl($pkg),
-                           htmlsanit($pkg),
-                           htmlmaintlinks(sub { $_[0] == 1 ? 'maintainer: '
+                           pkg_url(pkg => $pkg),
+                           html_escape($pkg),
+                           htmlize_maintlinks(sub { $_[0] == 1 ? 'maintainer: '
                                                            : 'maintainers: ' },
                                           $maintainers{$pkg}));
   }
@@ -101,7 +103,7 @@ if ($indexon eq "pkg") {
            } 
        } keys %count;
   }
-  %count = countbugs(sub {my %d=@_;
+  %count = countbugs(function => sub {my %d=@_;
                           return map {
                             $pkgsrc->{$_} || $_
                           } splitpackages($d{"pkg"});
@@ -111,15 +113,15 @@ if ($indexon eq "pkg") {
     $sortkey{$src} = lc $src;
     $htmldescrip{$src} = sprintf('<a href="%s">%s</a> (%s)',
                            srcurl($src),
-                           htmlsanit($src),
-                           htmlmaintlinks(sub { $_[0] == 1 ? 'maintainer: '
+                           html_escape($src),
+                           htmlize_maintlinks(sub { $_[0] == 1 ? 'maintainer: '
                                                            : 'maintainers: ' },
                                           $maintainers{$src}));
   }
 } elsif ($indexon eq "maint") {
   $tag = "maintainer";
   my %email2maint = ();
-  %count = countbugs(sub {my %d=@_;
+  %count = count_bugs(function => sub {my %d=@_;
                           return map {
                             my @me = getparsedaddrs($maintainers{$_});
                             foreach my $addr (@me) {
@@ -144,12 +146,12 @@ if ($indexon eq "pkg") {
   $note .= "different addresses.</p>\n";
   foreach my $maint (keys %count) {
     $sortkey{$maint} = lc $email2maint{$maint} || "(unknown)";
-    $htmldescrip{$maint} = htmlmaintlinks('', $email2maint{$maint});
+    $htmldescrip{$maint} = htmlize_maintlinks('', $email2maint{$maint});
   }
 } elsif ($indexon eq "submitter") {
   $tag = "submitter";
   my %fullname = ();
-  %count = countbugs(sub {my %d=@_;
+  %count = count_bugs(function => sub {my %d=@_;
                           my @se = getparsedaddrs($d{"submitter"} || "");
                           foreach my $addr (@se) {
                             $fullname{$addr->address} = $addr->format
@@ -171,14 +173,14 @@ if ($indexon eq "pkg") {
     $sortkey{$sub} = lc $fullname{$sub};
     $htmldescrip{$sub} = sprintf('<a href="%s">%s</a>',
                            submitterurl($sub),
-                          htmlsanit($fullname{$sub}));
+                          html_escape($fullname{$sub}));
   }
   $note = "<p>Note that people may use different email accounts for\n";
   $note .= "different bugs, so there may be other reports filed under\n";
   $note .= "different addresses.</p>\n";
 } elsif ($indexon eq "tag") {
   $tag = "tag";
-  %count = countbugs(sub {my %d=@_; return split ' ', $d{tags}; });
+  %count = count_bugs(function => sub {my %d=@_; return split ' ', $d{tags}; });
   if (defined $param{first}) {
        %count = map {
            if (/^\Q$param{first}\E/) {
@@ -194,7 +196,7 @@ if ($indexon eq "pkg") {
     $sortkey{$keyword} = lc $keyword;
     $htmldescrip{$keyword} = sprintf('<a href="%s">%s</a>',
                                tagurl($keyword),
-                               htmlsanit($keyword));
+                               html_escape($keyword));
   }
 }
 
index 734762f8956d7d337c4b1e59b8d8b964438fdb9c..cffc324bc02b0d4a0dc93c8c57d856b03cc11243 100755 (executable)
 
 package debbugs;
 
+use warnings;
 use strict;
 use POSIX qw(strftime nice);
 
-require './common.pl';
-
 use Debbugs::Config qw(:globals :text :config);
 use Debbugs::User;
 use Debbugs::CGI qw(version_url maint_decode);
-use Debbugs::Common qw(getparsedaddrs :date make_list);
-use Debbugs::Bugs qw(get_bugs);
+use Debbugs::Common qw(getparsedaddrs :date make_list getmaintainers);
+use Debbugs::Bugs qw(get_bugs bug_filter);
 use Debbugs::Packages qw(getsrcpkgs getpkgsrc get_versions);
-use Debbugs::Status qw(get_bug_status);
+use Debbugs::Status qw(:status);
+use Debbugs::CGI qw(:all);
 
 use vars qw($gPackagePages $gWebDomain %gSeverityDisplay @gSeverityList);
 
@@ -34,23 +34,20 @@ if (defined $ENV{REQUEST_METHOD} and $ENV{REQUEST_METHOD} eq 'HEAD') {
 
 nice(5);
 
-my $userAgent = detect_user_agent();
-
 use CGI::Simple;
 my $q = new CGI::Simple;
-#my %param = readparse();
-
-my %param = cgi_parameters(query => $q,
-                          single => [qw(ordering archive repeatmerged),
-                                     qw(bug-rev pend-rev sev-rev),
-                                     qw(maxdays mindays version),
-                                     qw(data which dist),
-                                    ],
-                          default => {ordering => 'normal',
-                                      archive  => 0,
-                                      repeatmerged => 1,
-                                     },
-                         );
+
+our %param = cgi_parameters(query => $q,
+                           single => [qw(ordering archive repeatmerged),
+                                      qw(bug-rev pend-rev sev-rev),
+                                      qw(maxdays mindays version),
+                                      qw(data which dist),
+                                     ],
+                           default => {ordering => 'normal',
+                                       archive  => 0,
+                                       repeatmerged => 1,
+                                      },
+                          );
 
 # map from yes|no to 1|0
 for my $key (qw(repeatmerged bug-rev pend-rev sev-rev)) {
@@ -72,7 +69,6 @@ elsif (lc($param{archive}) eq 'yes') {
 }
 
 
-my $repeatmerged = ($param{'repeatmerged'} || "yes") eq "yes";
 my $archive = ($param{'archive'} || "no") eq "yes";
 my $include = $param{'&include'} || $param{'include'} || "";
 my $exclude = $param{'&exclude'} || $param{'exclude'} || "";
@@ -104,8 +100,6 @@ my $mindays = ($param{'mindays'} || 0);
 my $version = $param{'version'} || undef;
 my $dist = $param{'dist'} || undef;
 my $arch = $param{'arch'} || undef;
-my $show_list_header = ($param{'show_list_header'} || $userAgent->{'show_list_header'} || "yes" ) eq "yes";
-my $show_list_footer = ($param{'show_list_footer'} || $userAgent->{'show_list_footer'} || "yes" ) eq "yes";
 
 {
     if (defined $param{'vt'}) {
@@ -163,7 +157,7 @@ our %cats = (
 );
 
 my @select_key = (qw(submitter maint pkg package src usertag),
-                 qw(status tag maintenc owner)
+                 qw(status tag maintenc owner severity)
                 );
 
 if (exists $param{which} and exists $param{data}) {
@@ -212,7 +206,9 @@ if (defined $param{usertag}) {
 
 my $Archived = $archive ? " Archived" : "";
 
-my $this = "";
+our $this = munge_url('pkgreport.cgi?',
+                     %param,
+                    );
 
 my %indexentry;
 my %strings = ();
@@ -250,7 +246,7 @@ sub add_user {
             push @{$bugusertags{$b}}, $t;
         }
     }
-    set_option("bugusertags", \%bugusertags);
+#    set_option("bugusertags", \%bugusertags);
 }
 
 my @bugs;
@@ -292,8 +288,6 @@ my %search_keys = @search_key_order;
 
 # Set the title sanely and clean up parameters
 my @title;
-use Data::Dumper;
-print STDERR Dumper(\%param);
 while (my ($key,$value) = splice @search_key_order, 0, 2) {
      next unless exists $param{$key};
      my @entries = ();
@@ -344,7 +338,7 @@ elsif (defined $param{dist}) {
      $title .= " in $dist";
 }
 
-$title = htmlsanit($title);
+$title = html_escape($title);
 
 my @names; my @prior; my @order;
 determine_ordering();
@@ -389,12 +383,12 @@ for my $package (make_list($param{src}||[])) {
 
 sub output_package_info{
     my ($srcorbin,$package) = @_;
-    my $showpkg = htmlsanit($package);
+    my $showpkg = html_escape($package);
     my $maintainers = getmaintainers();
     my $maint = $maintainers->{$package};
     if (defined $maint) {
         print '<p>';
-        print htmlmaintlinks(sub { $_[0] == 1 ? "Maintainer for $showpkg is "
+        print htmlize_maintlinks(sub { $_[0] == 1 ? "Maintainer for $showpkg is "
                                         : "Maintainers for $showpkg are "
                                    },
                              $maint);
@@ -418,7 +412,7 @@ sub output_package_info{
              print "<p>You may want to refer to the following individual bug pages:\n";
         }
         #push @pkgs, $src if ( $src && !grep(/^\Q$src\E$/, @pkgs) );
-        print join( ", ", map( "<A href=\"" . pkgurl($_) . "\">$_</A>", @pkgs ) );
+        print join( ", ", map( "<A href=\"" . html_escape(munge_url($this,package=>$_)) . "\">$_</A>", @pkgs ) );
         print ".\n";
     }
     my @references;
@@ -429,7 +423,7 @@ sub output_package_info{
     } else {
         if ($package and defined $gPackagePages) {
              push @references, sprintf "to the <a href=\"%s\">%s package page</a>",
-                  urlsanit("http://${debbugs::gPackagePages}/$package"), htmlsanit("$package");
+                  html_escape("http://${debbugs::gPackagePages}/$package"), html_escape("$package");
         }
         if (defined $gSubscriptionDomain) {
              my $ptslink = $package ? $srcforpkg : $src;
@@ -437,7 +431,7 @@ sub output_package_info{
         }
         # Only output this if the source listing is non-trivial.
         if ($srcorbin eq 'binary' and $srcforpkg) {
-             push @references, sprintf "to the source package <a href=\"%s\">%s</a>'s bug page", srcurl($srcforpkg), htmlsanit($srcforpkg);
+             push @references, sprintf "to the source package <a href=\"%s\">%s</a>'s bug page", html_escape(munge_url($this,src=>$srcforpkg,package=>[])), html_escape($srcforpkg);
         }
     }
     if (@references) {
@@ -447,12 +441,12 @@ sub output_package_info{
     if (defined $param{maint} || defined $param{maintenc}) {
         print "<p>If you find a bug not listed here, please\n";
         printf "<a href=\"%s\">report it</a>.</p>\n",
-             urlsanit("http://${debbugs::gWebDomain}/Reporting${debbugs::gHTMLSuffix}");
+             html_escape("http://${debbugs::gWebDomain}/Reporting${debbugs::gHTMLSuffix}");
     }
     if (not $maint and not @bugs) {
         print "<p>There is no record of the " .
-             ($srcorbin eq 'binary' ? htmlsanit($package) . " package"
-              : htmlsanit($src) . " source package").
+             ($srcorbin eq 'binary' ? html_escape($package) . " package"
+              : html_escape($src) . " source package").
                    ", and no bugs have been filed against it.</p>";
         $showresult = 0;
     }
@@ -478,7 +472,7 @@ my %archive_values = (both => 'archived and unarchived',
 while (my ($key,$value) = each %archive_values) {
      next if $key eq lc($param{archive});
      push @archive_links, qq(<a href=").
-         urlsanit(pkg_url((
+         html_escape(pkg_url((
                       map {
                            $_ eq 'archive'?():($_,$param{$_})
                       } keys %param),
@@ -511,27 +505,27 @@ print "<tr><td></td>";
 print "    <td><input id=\"b_1_2\" name=vt value=bysuite type=radio onchange=\"enable(1);\" $checked_sui>" . pkg_htmlselectsuite(1,2,1) . " for " . pkg_htmlselectarch(1,2,2) . "</td></tr>\n";
 
 if (defined $pkg) {
-    my $v = htmlsanit($version) || "";
-    my $pkgsane = htmlsanit($pkg);
+    my $v = html_escape($version) || "";
+    my $pkgsane = html_escape($pkg);
     print "<tr><td></td>";
     print "    <td><input id=\"b_1_3\" name=vt value=bypkg type=radio onchange=\"enable(1);\" $checked_ver>$pkgsane version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
 } elsif (defined $src) {
-    my $v = htmlsanit($version) || "";
-    my $srcsane = htmlsanit($src);
+    my $v = html_escape($version) || "";
+    my $srcsane = html_escape($src);
     print "<tr><td></td>";
     print "    <td><input name=vt value=bysrc type=radio onchange=\"enable(1);\" $checked_ver>$srcsane version <input id=\"b_1_3_1\" name=version value=\"$v\"></td></tr>\n";
 }
 print "<tr><td>&nbsp;</td></tr>\n";
 
-my $includetags = htmlsanit(join(" ", grep { !m/^subj:/i } map {split /[\s,]+/} ref($include)?@{$include}:$include));
-my $excludetags = htmlsanit(join(" ", grep { !m/^subj:/i } map {split /[\s,]+/} ref($exclude)?@{$exclude}:$exclude));
-my $includesubj = htmlsanit(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } map {split /[\s,]+/} ref($include)?@{$include}:$include));
-my $excludesubj = htmlsanit(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } map {split /[\s,]+/} ref($exclude)?@{$exclude}:$exclude));
+my $includetags = html_escape(join(" ", grep { !m/^subj:/i } map {split /[\s,]+/} ref($include)?@{$include}:$include));
+my $excludetags = html_escape(join(" ", grep { !m/^subj:/i } map {split /[\s,]+/} ref($exclude)?@{$exclude}:$exclude));
+my $includesubj = html_escape(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } map {split /[\s,]+/} ref($include)?@{$include}:$include));
+my $excludesubj = html_escape(join(" ", map { s/^subj://i; $_ } grep { m/^subj:/i } map {split /[\s,]+/} ref($exclude)?@{$exclude}:$exclude));
 my $vismindays = ($mindays == 0 ? "" : $mindays);
 my $vismaxdays = ($maxdays == -1 ? "" : $maxdays);
 
-my $sel_rmy = ($repeatmerged ? " selected" : "");
-my $sel_rmn = ($repeatmerged ? "" : " selected");
+my $sel_rmy = ($param{repeatmerged} ? " selected" : "");
+my $sel_rmn = ($param{repeatmerged} ? "" : " selected");
 my $sel_ordraw = ($ordering eq "raw" ? " selected" : "");
 my $sel_ordold = ($ordering eq "oldview" ? " selected" : "");
 my $sel_ordnor = ($ordering eq "normal" ? " selected" : "");
@@ -623,13 +617,13 @@ sub pkg_htmlindexentrystatus {
     my $showversions = '';
     if (@{$status{found_versions}}) {
         my @found = @{$status{found_versions}};
-        $showversions .= join ', ', map {s{/}{ }; htmlsanit($_)} @found;
+        $showversions .= join ', ', map {s{/}{ }; html_escape($_)} @found;
     }
     if (@{$status{fixed_versions}}) {
         $showversions .= '; ' if length $showversions;
         $showversions .= '<strong>fixed</strong>: ';
         my @fixed = @{$status{fixed_versions}};
-        $showversions .= join ', ', map {s{/}{ }; htmlsanit($_)} @fixed;
+        $showversions .= join ', ', map {s{/}{ }; html_escape($_)} @fixed;
     }
     $result .= ' (<a href="'.
         version_url($status{package},
@@ -641,10 +635,10 @@ sub pkg_htmlindexentrystatus {
     $result .= $showseverity;
     $result .= pkg_htmladdresslinks("Reported by: ", \&submitterurl,
                                 $status{originator});
-    $result .= ";\nOwned by: " . htmlsanit($status{owner})
+    $result .= ";\nOwned by: " . html_escape($status{owner})
                if length $status{owner};
     $result .= ";\nTags: <strong>" 
-                 . htmlsanit(join(", ", sort(split(/\s+/, $status{tags}))))
+                 . html_escape(join(", ", sort(split(/\s+/, $status{tags}))))
                  . "</strong>"
                        if (length($status{tags}));
 
@@ -656,7 +650,7 @@ sub pkg_htmlindexentrystatus {
         split(/ /,$status{blocks}));
 
     if (length($status{done})) {
-        $result .= "<br><strong>Done:</strong> " . htmlsanit($status{done});
+        $result .= "<br><strong>Done:</strong> " . html_escape($status{done});
         my $days = bug_archiveable(bug => $status{id},
                                   status => \%status,
                                   days_until => 1,
@@ -741,12 +735,19 @@ sub pkg_htmlizebugs {
     foreach my $bug (@bugs) {
         my %status = %{get_bug_status(bug=>$bug,
                                      (exists $param{dist}?(dist => $param{dist}):()),
+                                     usertags => \%bugusertags,
+                                     (exists $param{version}?(version => $param{version}):()),
+                                     (exists $param{arch}?(arch => $param{arch}):()),
                                     )};
         next unless %status;
-        next if bugfilter($bug, %status);
+        next if bug_filter(bug => $bug,
+                          status => \%status,
+                          (exists $param{repeatmerged}?(repeat_merged => $param{repeatmerged}):()),
+                          seen_merged => \%seenmerged,
+                         );
 
        my $html = sprintf "<li><a href=\"%s\">#%d: %s</a>\n<br>",
-            bugurl($bug), $bug, htmlsanit($status{subject});
+            bug_url($bug), $bug, html_escape($status{subject});
         $html .= pkg_htmlindexentrystatus(\%status) . "\n";
        push @status, [ $bug, \%status, $html ];
     }
@@ -792,7 +793,7 @@ sub pkg_htmlizebugs {
                $title .= join("; ", grep {($_ || "") ne ""}
                        map { $title[$_]->[$ttl[$_]] } 1..$#ttl);
            }
-           $title = htmlsanit($title);
+           $title = html_escape($title);
 
             my $count = $count{"_$order"};
             my $bugs = $count == 1 ? "bug" : "bugs";
@@ -846,8 +847,8 @@ sub pkg_htmlpackagelinks {
     return 'Package' . (@pkglist > 1 ? 's' : '') . ': ' .
            join(', ',
                 map {
-                    '<a class="submitter" href="' . pkgurl($_) . '">' .
-                    $openstrong . htmlsanit($_) . $closestrong . '</a>'
+                    '<a class="submitter" href="' . munge_url($this,src=>[],package=>$_) . '">' .
+                    $openstrong . html_escape($_) . $closestrong . '</a>'
                 } @pkglist
            );
 }
@@ -976,7 +977,7 @@ sub pkg_htmlselectarch {
 }
 
 sub myurl {
-     return urlsanit(pkg_url(map {exists $param{$_}?($_,$param{$_}):()}
+     return html_escape(pkg_url(map {exists $param{$_}?($_,$param{$_}):()}
                             qw(archive repeatmerged mindays maxdays),
                             qw(version dist arch pkg src tag maint submitter)
                            )