From 591a559c12f2cdf88c37b13b86b622f2d9da8996 Mon Sep 17 00:00:00 2001
From: vfilippov
Date: Fri, 25 Jun 2010 16:04:36 +0000
Subject: [PATCH] Bug 40933 - Merge with 3.6.1, Bug 64562 - Display "Next bug
in your list..."
git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@812 6955db30-a419-402b-8a0d-67ecbb4d7f56
---
Bugzilla/Bug.pm | 9 +-
Bugzilla/Constants.pm | 3 +-
Bugzilla/Group.pm | 2 +-
Bugzilla/Install/CPAN.pm | 91 ++++++++++++++++---
Bugzilla/Install/DB.pm | 7 ++
Bugzilla/Install/Filesystem.pm | 14 +++
Bugzilla/Install/Localconfig.pm | 4 +-
Bugzilla/Install/Requirements.pm | 9 +-
Bugzilla/Search.pm | 25 ++++-
Bugzilla/Template.pm | 4 +-
Bugzilla/Template/Plugin/Hook.pm | 7 +-
attachment.cgi | 2 +
colchange.cgi | 12 ++-
collectstats.pl | 8 ++
docs/en/html/Bugzilla-Guide.html | 8 +-
docs/en/html/about.html | 8 +-
docs/en/html/administration.html | 4 +-
docs/en/html/api/Bugzilla/Install/CPAN.html | 6 +-
docs/en/html/api/email_in.html | 4 -
docs/en/html/api/index.html | 4 +-
docs/en/html/attachments.html | 4 +-
docs/en/html/bug_page.html | 4 +-
docs/en/html/bug_status_workflow.html | 4 +-
docs/en/html/bugreports.html | 4 +-
docs/en/html/classifications.html | 4 +-
docs/en/html/cmdline-bugmail.html | 4 +-
docs/en/html/cmdline.html | 4 +-
docs/en/html/components.html | 4 +-
docs/en/html/configuration.html | 4 +-
docs/en/html/conventions.html | 4 +-
docs/en/html/copyright.html | 4 +-
docs/en/html/credits.html | 4 +-
docs/en/html/cust-change-permissions.html | 4 +-
docs/en/html/cust-skins.html | 4 +-
docs/en/html/cust-templates.html | 4 +-
docs/en/html/custom-fields.html | 4 +-
docs/en/html/customization.html | 4 +-
docs/en/html/disclaimer.html | 4 +-
docs/en/html/edit-values.html | 4 +-
docs/en/html/extensions.html | 4 +-
docs/en/html/extraconfig.html | 4 +-
docs/en/html/flags-overview.html | 4 +-
docs/en/html/flags.html | 4 +-
docs/en/html/general-advice.html | 4 +-
docs/en/html/gfdl-0.html | 4 +-
docs/en/html/gfdl-1.html | 4 +-
docs/en/html/gfdl-10.html | 4 +-
docs/en/html/gfdl-2.html | 4 +-
docs/en/html/gfdl-3.html | 4 +-
docs/en/html/gfdl-4.html | 4 +-
docs/en/html/gfdl-5.html | 4 +-
docs/en/html/gfdl-6.html | 4 +-
docs/en/html/gfdl-7.html | 4 +-
docs/en/html/gfdl-8.html | 4 +-
docs/en/html/gfdl-9.html | 4 +-
docs/en/html/gfdl-howto.html | 4 +-
docs/en/html/gfdl.html | 4 +-
docs/en/html/glossary.html | 4 +-
docs/en/html/groups.html | 4 +-
docs/en/html/hintsandtips.html | 4 +-
docs/en/html/index.html | 6 +-
docs/en/html/install-perlmodules-manual.html | 4 +-
docs/en/html/installation.html | 4 +-
docs/en/html/installing-bugzilla.html | 4 +-
docs/en/html/integration.html | 4 +-
docs/en/html/keywords.html | 4 +-
docs/en/html/lifecycle.html | 4 +-
docs/en/html/milestones.html | 4 +-
docs/en/html/modules-manual-download.html | 4 +-
docs/en/html/modules-manual-instructions.html | 4 +-
docs/en/html/modules-manual-optional.html | 4 +-
docs/en/html/multiple-bz-dbs.html | 4 +-
docs/en/html/myaccount.html | 4 +-
docs/en/html/newversions.html | 6 +-
docs/en/html/nonroot.html | 4 +-
docs/en/html/os-specific.html | 4 +-
docs/en/html/parameters.html | 4 +-
docs/en/html/paranoid-security.html | 4 +-
docs/en/html/patches.html | 4 +-
docs/en/html/products.html | 4 +-
docs/en/html/query.html | 4 +-
docs/en/html/quips.html | 4 +-
docs/en/html/reporting.html | 4 +-
docs/en/html/sanitycheck.html | 4 +-
docs/en/html/security-bugzilla.html | 4 +-
docs/en/html/security-os.html | 4 +-
docs/en/html/security-webserver.html | 4 +-
docs/en/html/security.html | 4 +-
docs/en/html/timetracking.html | 4 +-
docs/en/html/trbl-dbdsponge.html | 4 +-
docs/en/html/trbl-index.html | 4 +-
docs/en/html/trbl-passwd-encryption.html | 4 +-
docs/en/html/trbl-perlmodule.html | 4 +-
docs/en/html/trbl-relogin-everyone.html | 4 +-
docs/en/html/trbl-testserver.html | 4 +-
docs/en/html/troubleshooting.html | 4 +-
docs/en/html/upgrade.html | 4 +-
docs/en/html/useradmin.html | 4 +-
docs/en/html/userpreferences.html | 4 +-
docs/en/html/using-intro.html | 4 +-
docs/en/html/using.html | 4 +-
docs/en/html/versions.html | 4 +-
docs/en/html/voting.html | 4 +-
docs/en/html/whining.html | 4 +-
docs/en/txt/Bugzilla-Guide.txt | 6 +-
docs/en/xml/Bugzilla-Guide.xml | 6 +-
editvalues.cgi | 4 +-
email_in.pl | 6 --
install-module.pl | 20 ++--
process_bug.cgi | 4 +-
show_bug.cgi | 3 +-
.../default/admin/components/list.html.tmpl | 12 ++-
.../default/admin/milestones/list.html.tmpl | 2 +
.../default/admin/params/attachment.html.tmpl | 5 +-
.../en/default/admin/products/list.html.tmpl | 2 +
.../en/default/admin/versions/list.html.tmpl | 2 +
template/en/default/bug/show.html.tmpl | 8 +-
.../default/global/choose-product.html.tmpl | 2 +-
template/en/default/global/header.html.tmpl | 1 +
template/en/default/list/table.html.tmpl | 2 +
.../en/default/pages/quicksearch.html.tmpl | 4 +-
.../en/default/pages/release-notes.html.tmpl | 44 +++++++++
122 files changed, 435 insertions(+), 269 deletions(-)
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 568819626..f4ded0758 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -1647,7 +1647,9 @@ sub _check_resolution {
ThrowUserError('resolution_not_allowed') if $self->status->is_open;
# Check noresolveonopenblockers.
- if (Bugzilla->params->{"noresolveonopenblockers"} && $resolution eq 'FIXED')
+ if (Bugzilla->params->{"noresolveonopenblockers"}
+ && $resolution eq 'FIXED'
+ && (!$self->resolution || $resolution ne $self->resolution))
{
my @dependencies = CountOpenDependencies($self->id);
if (@dependencies) {
@@ -3336,7 +3338,10 @@ sub GetBugActivity {
if ($activity_visible) {
# Check for the results of an old Bugzilla data corruption bug
- $incomplete_data = 1 if ($added =~ /^\?/ || $removed =~ /^\?/);
+ if (($added eq '?' && $removed eq '?')
+ || ($added =~ /^\? / || $removed =~ /^\? /)) {
+ $incomplete_data = 1;
+ }
# An operation, done by 'who' at time 'when', has a number of
# 'changes' associated with it.
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 147aa7f80..1b96e19ee 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -182,7 +182,7 @@ use File::Basename;
# CONSTANTS
#
# Bugzilla version
-use constant BUGZILLA_VERSION => "3.6";
+use constant BUGZILLA_VERSION => "3.6.1";
# These are unique values that are unlikely to match a string or a number,
# to be used in criteria for match() functions and other things. They start
@@ -406,6 +406,7 @@ use constant contenttypes =>
"atom"=> "application/atom+xml" ,
"xml" => "application/xml" ,
"js" => "application/x-javascript" ,
+ "json"=> "application/json" ,
"csv" => "text/csv" ,
"png" => "image/png" ,
"ics" => "text/calendar" ,
diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm
index 65df4ee81..f24eef735 100644
--- a/Bugzilla/Group.pm
+++ b/Bugzilla/Group.pm
@@ -437,7 +437,7 @@ sub _check_name {
$name = trim($name);
$name || ThrowUserError("empty_group_name");
# If we're creating a Group or changing the name...
- if (!ref($invocant) || $invocant->name ne $name) {
+ if (!ref($invocant) || lc($invocant->name) ne lc($name)) {
my $exists = new Bugzilla::Group({name => $name });
ThrowUserError("group_exists", { name => $name }) if $exists;
}
diff --git a/Bugzilla/Install/CPAN.pm b/Bugzilla/Install/CPAN.pm
index b37e6d40d..af50b52e4 100644
--- a/Bugzilla/Install/CPAN.pm
+++ b/Bugzilla/Install/CPAN.pm
@@ -21,9 +21,16 @@
package Bugzilla::Install::CPAN;
use strict;
use base qw(Exporter);
-our @EXPORT = qw(set_cpan_config install_module BZ_LIB);
+our @EXPORT = qw(
+ BZ_LIB
+
+ check_cpan_requirements
+ set_cpan_config
+ install_module
+);
use Bugzilla::Constants;
+use Bugzilla::Install::Requirements qw(have_vers);
use Bugzilla::Install::Util qw(bin_loc install_string);
use CPAN;
@@ -31,6 +38,24 @@ use Cwd qw(abs_path);
use File::Path qw(rmtree);
use List::Util qw(shuffle);
+# These are required for install-module.pl to be able to install
+# all modules properly.
+use constant REQUIREMENTS => (
+ {
+ module => 'CPAN',
+ package => 'CPAN',
+ version => '1.81',
+ },
+ {
+ # When Module::Build isn't installed, the YAML module allows
+ # CPAN to read META.yml to determine that Module::Build first
+ # needs to be installed to compile a module.
+ module => 'YAML',
+ package => 'YAML',
+ version => 0,
+ },
+);
+
# We need the absolute path of ext_libpath, because CPAN chdirs around
# and so we can't use a relative directory.
#
@@ -46,6 +71,7 @@ use constant CPAN_DEFAULTS => {
auto_commit => 0,
# We always force builds, so there's no reason to cache them.
build_cache => 0,
+ build_requires_install_policy => 'yes',
cache_metadata => 1,
index_expire => 1,
scan_cache => 'atstart',
@@ -53,6 +79,7 @@ use constant CPAN_DEFAULTS => {
inhibit_startup_message => 1,
mbuild_install_build_command => './Build',
+ bzip2 => bin_loc('bzip2'),
curl => bin_loc('curl'),
gzip => bin_loc('gzip'),
links => bin_loc('links'),
@@ -67,14 +94,43 @@ use constant CPAN_DEFAULTS => {
http://cpan.pair.com/
http://mirror.hiwaay.net/CPAN/
ftp://ftp.dc.aleron.net/pub/CPAN/
- http://perl.secsup.org/
- http://mirrors.kernel.org/cpan/)],
+ http://mirrors.kernel.org/cpan/
+ http://mirrors2.kernel.org/cpan/)],
};
+sub check_cpan_requirements {
+ my ($original_dir, $original_args) = @_;
+
+ my @install;
+ foreach my $module (REQUIREMENTS) {
+ my $installed = have_vers($module, 1);
+ push(@install, $module) if !$installed;
+ }
+
+ return if !@install;
+
+ my $restart_required;
+ foreach my $module (@install) {
+ $restart_required = 1 if $module->{module} eq 'CPAN';
+ install_module($module->{module}, 1);
+ }
+
+ if ($restart_required) {
+ chdir $original_dir;
+ exec($^X, $0, @$original_args);
+ }
+}
+
sub install_module {
- my ($name, $notest) = @_;
+ my ($name, $test) = @_;
my $bzlib = BZ_LIB;
+ # Make Module::AutoInstall install all dependencies and never prompt.
+ local $ENV{PERL_AUTOINSTALL} = '--alldeps';
+ # This makes Net::SSLeay not prompt the user, if it gets installed.
+ # It also makes any other MakeMaker prompts accept their defaults.
+ local $ENV{PERL_MM_USE_DEFAULT} = 1;
+
# Certain modules require special stuff in order to not prompt us.
my $original_makepl = $CPAN::Config->{makepl_arg};
# This one's a regex in case we're doing Template::Plugin::GD and it
@@ -85,21 +141,22 @@ sub install_module {
elsif ($name eq 'XML::Twig') {
$CPAN::Config->{makepl_arg} = "-n $original_makepl";
}
- elsif ($name eq 'Net::LDAP') {
- $CPAN::Config->{makepl_arg} .= " --skipdeps";
- }
elsif ($name eq 'SOAP::Lite') {
$CPAN::Config->{makepl_arg} .= " --noprompt";
}
+ # MIME-tools has a Module::Install that's too old to understand alldeps.
+ elsif ($name =~ /^MIME::/) {
+ $ENV{PERL_AUTOINSTALL} = '--defaultdeps';
+ }
my $module = CPAN::Shell->expand('Module', $name);
print install_string('install_module',
{ module => $name, version => $module->cpan_version }) . "\n";
- if ($notest) {
- CPAN::Shell->notest('install', $name);
+ if ($test) {
+ CPAN::Shell->force('install', $name);
}
else {
- CPAN::Shell->force('install', $name);
+ CPAN::Shell->notest('install', $name);
}
# If it installed any binaries in the Bugzilla directory, delete them.
@@ -152,6 +209,8 @@ sub set_cpan_config {
# Unless specified, we install the modules into the Bugzilla directory.
if (!$do_global) {
+ require Config;
+
$CPAN::Config->{makepl_arg} .= " LIB=\"$bzlib\""
. " INSTALLMAN1DIR=\"$bzlib/man/man1\""
. " INSTALLMAN3DIR=\"$bzlib/man/man3\""
@@ -162,7 +221,10 @@ sub set_cpan_config {
# INSTALLDIRS=perl is set because that makes sure that MakeMaker
# always uses the directories we've specified here.
. " INSTALLDIRS=perl";
- $CPAN::Config->{mbuild_arg} = "--install_base \"$bzlib\"";
+ $CPAN::Config->{mbuild_arg} = " --install_base \"$bzlib\""
+ . " --install_path lib=\"$bzlib\""
+ . " --install_path arch=\"$bzlib/$Config::Config{archname}\"";
+ $CPAN::Config->{mbuild_install_arg} = $CPAN::Config->{mbuild_arg};
# When we're not root, sometimes newer versions of CPAN will
# try to read/modify things that belong to root, unless we set
@@ -213,7 +275,7 @@ Bugzilla::Install::CPAN - Routines to install Perl modules from CPAN.
use Bugzilla::Install::CPAN;
set_cpan_config();
- install_module('Module::Name', 1);
+ install_module('Module::Name');
=head1 DESCRIPTION
@@ -240,8 +302,9 @@ Installs a module from CPAN. Takes two arguments:
=item C<$name> - The name of the module, just like you'd pass to the
C command in the CPAN shell.
-=item C<$notest> - If true, we skip running tests on this module. This
-can greatly speed up the installation time.
+=item C<$test> - If true, we run tests on this module before installing,
+but we still force the install if the tests fail. This is only used
+when we internally install a newer CPAN module.
=back
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index d0863ba0a..d73567db7 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -1882,6 +1882,12 @@ sub _remove_spaces_and_commas_from_flagtypes {
sub _setup_usebuggroups_backward_compatibility {
my $dbh = Bugzilla->dbh;
+
+ # Don't run this on newer Bugzillas. This is a reliable test because
+ # the longdescs table existed in 2.16 (which had usebuggroups)
+ # but not in 2.18, and this code happens between 2.16 and 2.18.
+ return if $dbh->bz_column_info('longdescs', 'already_wrapped');
+
# 2002-11-24 - bugreport@peshkin.net - bug 147275
#
# If group_control_map is empty, backward-compatibility
@@ -1889,6 +1895,7 @@ sub _setup_usebuggroups_backward_compatibility {
my ($maps_exist) = $dbh->selectrow_array(
"SELECT DISTINCT 1 FROM group_control_map");
if (!$maps_exist) {
+ print "Converting old usebuggroups controls...\n";
# Initially populate group_control_map.
# First, get all the existing products and their groups.
my $sth = $dbh->prepare("SELECT groups.id, products.id, groups.name,
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index c08df1036..956cffcdb 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -75,6 +75,13 @@ sub FILESYSTEM {
my $skinsdir = bz_locations()->{'skinsdir'};
my $localconfig = bz_locations()->{'localconfig'};
+ # We want to set the permissions the same for all localconfig files
+ # across all PROJECTs, so we do something special with $localconfig,
+ # lower down in the permissions section.
+ if ($ENV{PROJECT}) {
+ $localconfig =~ s/\.\Q$ENV{PROJECT}\E$//;
+ }
+
my $ws_group = Bugzilla->localconfig->{'webservergroup'};
my $use_suexec = Bugzilla->localconfig->{'use_suexec'};
@@ -92,6 +99,9 @@ sub FILESYSTEM {
# Writeable by the web server.
my $ws_writeable = $ws_group ? 0660 : 0666;
+ # Script-readable files that should not be world-readable under suexec.
+ my $script_readable = $use_suexec ? 0640 : $ws_readable;
+
# DIRECTORIES
# Readable by the web server.
my $ws_dir_readable = ($ws_group && !$use_suexec) ? 0750 : 0755;
@@ -130,6 +140,10 @@ sub FILESYSTEM {
'migrate.pl' => { perms => $owner_executable },
'install-module.pl' => { perms => $owner_executable },
+ # Set the permissions for localconfig the same across all
+ # PROJECTs.
+ $localconfig => { perms => $script_readable },
+ "$localconfig.*" => { perms => $script_readable },
"$localconfig.old" => { perms => $owner_readable },
'contrib/README' => { perms => $owner_readable },
diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm
index 346746655..d5d76cb79 100644
--- a/Bugzilla/Install/Localconfig.pm
+++ b/Bugzilla/Install/Localconfig.pm
@@ -276,10 +276,10 @@ EOT
if (defined $$glob) {
$localconfig{$var} = $$glob;
}
- elsif (defined @$glob) {
+ elsif (@$glob) {
$localconfig{$var} = \@$glob;
}
- elsif (defined %$glob) {
+ elsif (%$glob) {
$localconfig{$var} = \%$glob;
}
}
diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm
index 60fc73ebd..73e570769 100644
--- a/Bugzilla/Install/Requirements.pm
+++ b/Bugzilla/Install/Requirements.pm
@@ -547,8 +547,9 @@ sub have_vers {
eval "require $module;";
- # VERSION is provided by UNIVERSAL::
- my $vnum = eval { $module->VERSION } || -1;
+ # VERSION is provided by UNIVERSAL::, and can be called even if
+ # the module isn't loaded.
+ my $vnum = $module->VERSION || -1;
# CGI's versioning scheme went 2.75, 2.751, 2.752, 2.753, 2.76
# That breaks the standard version tests, so we need to manually correct
@@ -556,6 +557,10 @@ sub have_vers {
if ($module eq 'CGI' && $vnum =~ /(2\.7\d)(\d+)/) {
$vnum = $1 . "." . $2;
}
+ # CPAN did a similar thing, where it has versions like 1.9304.
+ if ($module eq 'CPAN' and $vnum =~ /^(\d\.\d{2})\d{2}$/) {
+ $vnum = $1;
+ }
my $vstr;
if ($vnum eq "-1") { # string compare just in case it's non-numeric
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 19945d657..b2acc47b9 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -308,7 +308,14 @@ sub init {
my @legal_statuses =
map {$_->name} @{Bugzilla::Field->new({name => 'bug_status'})->legal_values};
- if (scalar(@bug_statuses) == scalar(@legal_statuses)
+ # Filter out any statuses that have been removed completely that are still
+ # being used by the client
+ my @valid_statuses;
+ foreach my $status (@bug_statuses) {
+ push(@valid_statuses, $status) if grep($_ eq $status, @legal_statuses);
+ }
+
+ if (scalar(@valid_statuses) == scalar(@legal_statuses)
|| $bug_statuses[0] eq "__all__")
{
$params->delete('bug_status');
@@ -321,6 +328,9 @@ sub init {
$params->param('bug_status', grep(!is_open_state($_),
@legal_statuses));
}
+ else {
+ $params->param('bug_status', @valid_statuses);
+ }
}
if ($params->param('resolution')) {
@@ -394,8 +404,8 @@ sub init {
}
}
- my $chfieldfrom = trim(lc($params->param('chfieldfrom'))) || '';
- my $chfieldto = trim(lc($params->param('chfieldto'))) || '';
+ my $chfieldfrom = trim(lc($params->param('chfieldfrom') || ''));
+ my $chfieldto = trim(lc($params->param('chfieldto') || ''));
$chfieldfrom = '' if ($chfieldfrom eq 'now');
$chfieldto = '' if ($chfieldto eq 'now');
my @chfield = $params->param('chfield');
@@ -851,6 +861,12 @@ sub init {
%chartfields = @{$dbh->selectcol_arrayref(
q{SELECT name, id FROM fielddefs}, { Columns=>[1,2] })};
+ if (!$user->is_timetracker) {
+ foreach my $tt_field (TIMETRACKING_FIELDS) {
+ delete $chartfields{$tt_field};
+ }
+ }
+
$row = 0;
for ($chart=-1 ;
$chart < 0 || $params->param("field$chart-0-0") ;
@@ -1259,8 +1275,7 @@ sub BuildOrderBy {
sub split_order_term {
my $fragment = shift;
$fragment =~ /^(.+?)(?:\s+(ASC|DESC))?$/i;
- my ($column_name, $direction) = (lc($1), uc($2));
- $direction ||= "";
+ my ($column_name, $direction) = (lc($1), uc($2 || ''));
return wantarray ? ($column_name, $direction) : $column_name;
}
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 36e8c6f7d..d8766b389 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -385,7 +385,7 @@ sub get_bug_link {
$title = html_quote(clean_text($title));
my $linkval = correct_urlbase()."show_bug.cgi?id=".$bug->id;
- if ($options->{comment_num}) {
+ if (defined $options->{comment_num}) {
$linkval .= "#c" . $options->{comment_num};
}
# CustIS Bug 53691
@@ -1004,7 +1004,7 @@ sub process
# if outputting via print(), check for sent header
Bugzilla->send_header;
}
- $self->SUPER::process(@_);
+ return $self->SUPER::process(@_);
}
1;
diff --git a/Bugzilla/Template/Plugin/Hook.pm b/Bugzilla/Template/Plugin/Hook.pm
index 7e43bbf91..5616a6464 100644
--- a/Bugzilla/Template/Plugin/Hook.pm
+++ b/Bugzilla/Template/Plugin/Hook.pm
@@ -46,8 +46,11 @@ sub process {
$template ||= $context->stash->get([ 'component', 0, 'name', 0 ]);
# sanity check:
- if ($template !~ /^[\w\.\/\-_\\]+$/) {
- ThrowCodeError('template_invalid', { name => $template });
+ # WHAT IDIOT HAS CALLED SPECIAL TT VARIABLE 'component'?
+ if ($template !~ /^[\w\.\/\-_\\]+$/)
+ {
+ warn __PACKAGE__.": Template component.name = '$template' invalid, skipping hooks";
+ return;
}
my (undef, $path, $filename) = File::Spec->splitpath($template);
diff --git a/attachment.cgi b/attachment.cgi
index 1940fb00e..0c300a7f8 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -385,6 +385,8 @@ sub viewall {
my $bugid = $bug->id;
my $attachments = Bugzilla::Attachment->get_attachments_by_bug($bugid);
+ # Ignore deleted attachments.
+ @$attachments = grep { $_->datasize } @$attachments;
# Define the variables and functions that will be passed to the UI template.
$vars->{'bug'} = $bug;
diff --git a/colchange.cgi b/colchange.cgi
index 6dbb3a3d1..f9161262a 100755
--- a/colchange.cgi
+++ b/colchange.cgi
@@ -152,10 +152,13 @@ if (defined $cgi->param('rememberedquery')) {
$vars->{'redirect_url'} = "buglist.cgi?".$params->query_string();
- # If we're running on Microsoft IIS, using cgi->redirect discards
- # the Set-Cookie lines -- workaround is to use the old-fashioned
- # redirection mechanism. See bug 214466 for details.
- if ($ENV{'SERVER_SOFTWARE'} =~ /Microsoft-IIS/
+ # If we're running on Microsoft IIS, $cgi->redirect discards
+ # the Set-Cookie lines. In mod_perl, $cgi->redirect with cookies
+ # causes the page to be rendered as text/plain.
+ # Workaround is to use the old-fashioned redirection mechanism.
+ # See bug 214466 and bug 376044 for details.
+ if ($ENV{'MOD_PERL'}
+ || $ENV{'SERVER_SOFTWARE'} =~ /Microsoft-IIS/
|| $ENV{'SERVER_SOFTWARE'} =~ /Sun ONE Web/)
{
$cgi->send_header(-type => "text/html",
@@ -163,6 +166,7 @@ if (defined $cgi->param('rememberedquery')) {
}
else {
print $cgi->redirect($vars->{'redirect_url'});
+ exit;
}
$template->process("global/message.html.tmpl", $vars)
diff --git a/collectstats.pl b/collectstats.pl
index 5f9b4eef3..d8987b2b9 100755
--- a/collectstats.pl
+++ b/collectstats.pl
@@ -201,6 +201,10 @@ sub collect_stats {
|| ThrowCodeError('chart_file_open_fail', {'filename' => $file});
}
+ if (Bugzilla->params->{'utf8'}) {
+ binmode DATA, ':utf8';
+ }
+
# Now collect current data.
my @row = (today());
my $status_sql = q{SELECT COUNT(*) FROM bugs WHERE bug_status = ?};
@@ -258,6 +262,10 @@ sub get_old_data {
open(DATA, '<', $file)
|| ThrowCodeError('chart_file_open_fail', {'filename' => $file});
+ if (Bugzilla->params->{'utf8'}) {
+ binmode DATA, ':utf8';
+ }
+
my @data;
my @columns;
my $recreate = 0;
diff --git a/docs/en/html/Bugzilla-Guide.html b/docs/en/html/Bugzilla-Guide.html
index 7111f610f..ce337f8ea 100644
--- a/docs/en/html/Bugzilla-Guide.html
+++ b/docs/en/html/Bugzilla-Guide.html
@@ -2,7 +2,7 @@
The Bugzilla Guide - 3.6
+>The Bugzilla Guide - 3.6.1
ReleaseThe Bugzilla Guide - 3.6
+>The Bugzilla Guide - 3.6.1
Release
The Bugzilla Team
2010-04-13
2010-06-24
1.3. New Versions
This is the 3.6 version of The Bugzilla Guide. It is so named
+>
This is the 3.6.1 version of The Bugzilla Guide. It is so named
to match the current version of Bugzilla.
Note that the email interface has the same limitations as the normal Bugzilla interface. So, for example, you cannot reassign a bug and change its status at the same time.
-
The email interface only accepts emails that are correctly formatted per RFC2822. If you send it an incorrectly formatted message, it may behave in an unpredictable fashion.
This is the 3.6 version of The Bugzilla Guide. It is so named
+>
This is the 3.6.1 version of The Bugzilla Guide. It is so named
to match the current version of Bugzilla.
-
-
-
+
+
+
diff --git a/editvalues.cgi b/editvalues.cgi
index e8a1c2212..de1806d45 100755
--- a/editvalues.cgi
+++ b/editvalues.cgi
@@ -185,11 +185,11 @@ if ($action eq 'edit') {
if ($action eq 'update') {
check_token_data($token, 'edit_field_value');
$vars->{'value_old'} = $value->name;
- $value->set_name($cgi->param('value_new'));
- $value->set_sortkey($cgi->param('sortkey'));
if (!($value->is_static || $value->is_default)) {
$value->set_is_active($cgi->param('is_active'));
}
+ $value->set_name($cgi->param('value_new'));
+ $value->set_sortkey($cgi->param('sortkey'));
$vars->{'changes'} = $value->update();
my $ch = $value->set_visibility_values([ $cgi->param('visibility_value_id') ]);
$vars->{'changes'}->{'visibility_values'} = $ch if defined $ch;
diff --git a/email_in.pl b/email_in.pl
index 77348fc18..76e2f9048 100755
--- a/email_in.pl
+++ b/email_in.pl
@@ -682,8 +682,6 @@ not send you anything.
If any part of your request fails, all of it will fail. No partial
changes will happen.
-There is no attachment support yet.
-
=head1 CAUTION
The script does not do any validation that the user is who they say
@@ -694,10 +692,6 @@ and only allow access to the inbound email system from people you trust.
=head1 LIMITATIONS
-Note that the email interface has the same limitations as the
-normal Bugzilla interface. So, for example, you cannot reassign
-a bug and change its status at the same time.
-
The email interface only accepts emails that are correctly formatted
per RFC2822. If you send it an incorrectly formatted message, it
may behave in an unpredictable fashion.
diff --git a/install-module.pl b/install-module.pl
index bfee113b7..ee3611791 100755
--- a/install-module.pl
+++ b/install-module.pl
@@ -26,7 +26,7 @@ use warnings;
# CPAN has chdir'ed around. We do all of this in this funny order to
# make sure that we use the lib/ modules instead of the base Perl modules,
# in case the lib/ modules are newer.
-use Cwd qw(abs_path);
+use Cwd qw(abs_path cwd);
use lib abs_path('.');
use Bugzilla::Constants;
use lib abs_path(bz_locations()->{ext_libpath});
@@ -35,14 +35,17 @@ use Bugzilla::Install::CPAN;
use Bugzilla::Constants;
use Bugzilla::Install::Requirements;
-use Bugzilla::Install::Util qw(bin_loc);
+use Bugzilla::Install::Util qw(bin_loc init_console vers_cmp);
use Data::Dumper;
use Getopt::Long;
use Pod::Usage;
-our %switch;
+init_console();
+my @original_args = @ARGV;
+my $original_dir = cwd();
+our %switch;
GetOptions(\%switch, 'all|a', 'upgrade-all|u', 'show-config|s', 'global|g',
'shell', 'help|h');
@@ -63,12 +66,7 @@ if ($switch{'show-config'}) {
exit;
}
-my $can_notest = 1;
-if (substr(CPAN->VERSION, 0, 3) < 1.8) {
- $can_notest = 0;
- print "* Note: If you upgrade your CPAN module, installs will be faster.\n";
- print "* You can upgrade CPAN by doing: $^X install-module.pl CPAN\n";
-}
+check_cpan_requirements($original_dir, \@original_args);
if ($switch{'shell'}) {
CPAN::shell();
@@ -100,12 +98,12 @@ if ($switch{'all'} || $switch{'upgrade-all'}) {
next if $cpan_name eq 'mod_perl2';
next if $cpan_name eq 'DBD::Oracle' and !$ENV{ORACLE_HOME};
next if $cpan_name eq 'DBD::Pg' and !bin_loc('pg_config');
- install_module($cpan_name, $can_notest);
+ install_module($cpan_name);
}
}
foreach my $module (@ARGV) {
- install_module($module, $can_notest);
+ install_module($module);
}
__END__
diff --git a/process_bug.cgi b/process_bug.cgi
index 2188748c4..c90014733 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -720,13 +720,13 @@ elsif (($action eq 'next_bug' or $action eq 'same_bug') && ($bug = $vars->{bug})
my $title;
if (scalar(@bug_objects) == 1)
{
- $title = template_var('terms')->{Bug} . ' ' . $bug->id . ' processed';
+ $title = template_var('terms')->{Bug} . ' ' . $bug_objects[0]->id . ' processed';
}
else
{
$title = template_var('terms')->{Bugs} . ' processed';
}
- if (Bugzilla->save_session_data({ sent => $send_results, title => $title }))
+ if (Bugzilla->save_session_data({ sent => $send_results, title => $title, nextbug => $action eq 'next_bug' ? 1 : 0 }))
{
print $cgi->redirect(-location => 'show_bug.cgi?id='.$bug->id);
exit;
diff --git a/show_bug.cgi b/show_bug.cgi
index 040e4e027..9a92450a9 100755
--- a/show_bug.cgi
+++ b/show_bug.cgi
@@ -126,7 +126,8 @@ $vars->{'displayfields'} = \%displayfields;
my $sd;
if (Bugzilla->session && ($sd = Bugzilla->session_data) && $sd->{sent})
{
- Bugzilla->save_session_data({ sent => undef, title => undef, header => undef });
+ Bugzilla->save_session_data({ sent => undef, title => undef, header => undef, nextbug => undef });
+ $vars->{nextbug} = $sd->{nextbug};
$vars->{last_title} = $sd->{title};
$vars->{last_header} = $sd->{header};
$vars->{sentmail} = $sd->{sent};
diff --git a/template/en/default/admin/components/list.html.tmpl b/template/en/default/admin/components/list.html.tmpl
index 53bce072e..7c93f719a 100644
--- a/template/en/default/admin/components/list.html.tmpl
+++ b/template/en/default/admin/components/list.html.tmpl
@@ -97,19 +97,21 @@
[% overrides.initialowner = {} %]
[% overrides.initialqacontact = {} %]
-[% FOREACH component = product.components %]
- [% overrides.initialowner.name.${component.name} = {
+[% FOREACH c = product.components %]
+ [% overrides.initialowner.name.${c.name} = {
override_content => 1
- content => component.default_assignee.login
+ content => c.default_assignee.login
}
%]
- [% overrides.initialqacontact.name.${component.name} = {
+ [% overrides.initialqacontact.name.${c.name} = {
override_content => 1
- content => component.default_qa_contact.login
+ content => c.default_qa_contact.login
}
%]
[% END %]
+[% Hook.process('before_table') %]
+
[% PROCESS admin/table.html.tmpl
columns = columns
data = product.components
diff --git a/template/en/default/admin/milestones/list.html.tmpl b/template/en/default/admin/milestones/list.html.tmpl
index e1463603c..9422855ac 100644
--- a/template/en/default/admin/milestones/list.html.tmpl
+++ b/template/en/default/admin/milestones/list.html.tmpl
@@ -86,6 +86,8 @@
}
%]
+[% Hook.process('before_table') %]
+
[% PROCESS admin/table.html.tmpl
columns = columns
data = product.milestones
diff --git a/template/en/default/admin/params/attachment.html.tmpl b/template/en/default/admin/params/attachment.html.tmpl
index 749b4a583..2420a119b 100644
--- a/template/en/default/admin/params/attachment.html.tmpl
+++ b/template/en/default/admin/params/attachment.html.tmpl
@@ -66,9 +66,8 @@
maxattachmentsize => "The maximum size (in kilobytes) of attachments. " _
"$terms.Bugzilla will not accept attachments greater than this number " _
- "of kilobytes in size. To accept attachments of any size " _
- "(subject to the limitations of your server software), set this " _
- "value to zero.",
+ "of kilobytes in size. Setting this parameter to 0 will prevent " _
+ "attaching files to ${terms.bugs}.",
maxlocalattachment => "The maximum size (in megabytes) of attachments identified by " _
"the user as 'Big Files' to be stored locally on the webserver. " _
diff --git a/template/en/default/admin/products/list.html.tmpl b/template/en/default/admin/products/list.html.tmpl
index 6fd5240af..57d75d886 100644
--- a/template/en/default/admin/products/list.html.tmpl
+++ b/template/en/default/admin/products/list.html.tmpl
@@ -100,6 +100,8 @@
})
%]
+[% Hook.process('before_table') %]
+
[% PROCESS admin/table.html.tmpl
columns = columns
data = products
diff --git a/template/en/default/admin/versions/list.html.tmpl b/template/en/default/admin/versions/list.html.tmpl
index 45e33336c..401ee519b 100644
--- a/template/en/default/admin/versions/list.html.tmpl
+++ b/template/en/default/admin/versions/list.html.tmpl
@@ -68,6 +68,8 @@
})
%]
+[% Hook.process('before_table') %]
+
[% PROCESS admin/table.html.tmpl
columns = columns
data = product.versions
diff --git a/template/en/default/bug/show.html.tmpl b/template/en/default/bug/show.html.tmpl
index 6eb4a7396..8316bcacd 100644
--- a/template/en/default/bug/show.html.tmpl
+++ b/template/en/default/bug/show.html.tmpl
@@ -28,12 +28,8 @@
[% IF !header_done %]
[% PROCESS "bug/show-header.html.tmpl" %]
- [% IF last_title;
- SET title = last_title;
- END;
- IF last_header;
- SET header = last_header;
- END %]
+ [% IF last_title; SET title = last_title; END;
+ IF last_header; SET header = last_header; END; %]
[% PROCESS global/header.html.tmpl %]
[% END %]
diff --git a/template/en/default/global/choose-product.html.tmpl b/template/en/default/global/choose-product.html.tmpl
index 88bae1351..192bcfe8d 100644
--- a/template/en/default/global/choose-product.html.tmpl
+++ b/template/en/default/global/choose-product.html.tmpl
@@ -34,7 +34,7 @@
[% title = "Enter $terms.Bug" %]
[% h2 = BLOCK %]First, you must pick a product on which to enter [% terms.abug %]: [% END %]
[% ELSIF target == "describecomponents.cgi" %]
- [% title = "$terms.Bugzilla: Browse" %]
+ [% title = "Browse" %]
[% h2 = "Select a product category to browse:" %]
[% END %]
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index db82dd3ba..c2c5630e9 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -64,6 +64,7 @@
"http://www.w3.org/TR/html4/loose.dtd">
+ [% Hook.process("start") %]
[% title %]
[%# Migration note: contents of the old Param 'headerhtml' would go here %]
diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl
index ddfb40466..06e76bc02 100644
--- a/template/en/default/list/table.html.tmpl
+++ b/template/en/default/list/table.html.tmpl
@@ -154,6 +154,8 @@
[%# Bug Table #%]
[%############################################################################%]
+[% Hook.process("before_table") %]
+
[% tableheader %]
If you want to search specific fields, you do it like
field:value, where field is one of the
field names lower down in this
- document, and value is the value you want to search for
- in that field. If put commas in the value, then it is
+ document and value is the value you want to search for
+ in that field. If you put commas in the value, then it is
interpreted as a list of values, and [% terms.bugs %] that match
any of those values will be searched for.
It is now possible to upgrade from 3.4 to 3.6 when using Oracle.
+ ([% terms.Bug %] 561379)
+
+
Editing a field value's name (using the Field Values admin control
+ panel) wasn't working if the value was set as the default for that
+ field.
+ ([% terms.Bug %] 561296)
+
+
If you had the noresolveonopenblockers parameter set,
+ [%+ terms.bugs %] couldn't be edited at all if they were marked FIXED
+ and had any open blockers. (The parameter is only supposed to prevent
+ changing [% terms.bugs %] to FIXED, not modifying already-FIXED
+ [%+ terms.bugs %].)
+ ([% terms.Bug %] 565314)
+
+
Some minor issues with Perl 5.12 were fixed (mostly warnings that Perl
+ 5.12 was throwing). [% terms.Bugzilla %] now supports Perl 5.12.
+
+
Minimum Requirements
Any requirements that are new since 3.4.5 will look like