aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Ruppert <idl0r@gentoo.org>2016-06-18 13:35:57 +0200
committerChristian Ruppert <idl0r@gentoo.org>2016-06-18 13:35:57 +0200
commit5ba92938780af94afd6b9cc5ed5bde4d9f0e85d5 (patch)
tree123709dae18f3b81a214a2d331fbec2f3c678fdf
parentImport Bugzilla::Error for ThrowUserError (diff)
parentBumped version to 5.0.3 (diff)
downloadbugzilla-5ba92938780af94afd6b9cc5ed5bde4d9f0e85d5.tar.gz
bugzilla-5ba92938780af94afd6b9cc5ed5bde4d9f0e85d5.tar.bz2
bugzilla-5ba92938780af94afd6b9cc5ed5bde4d9f0e85d5.zip
Merge tag 'release-5.0.3' into bugstest
-rw-r--r--.bzrignore1
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml78
-rw-r--r--Bugzilla.pm3
-rw-r--r--Bugzilla/Attachment.pm3
-rw-r--r--Bugzilla/Bug.pm14
-rw-r--r--Bugzilla/BugMail.pm4
-rw-r--r--Bugzilla/BugUrl.pm5
-rw-r--r--Bugzilla/CGI.pm5
-rw-r--r--Bugzilla/Component.pm5
-rw-r--r--Bugzilla/Constants.pm4
-rw-r--r--Bugzilla/DB/Schema/Mysql.pm2
-rw-r--r--Bugzilla/MIME.pm17
-rw-r--r--Bugzilla/Search.pm3
-rw-r--r--Bugzilla/Template.pm23
-rw-r--r--Bugzilla/Util.pm4
-rw-r--r--Bugzilla/WebService/Bug.pm4
-rw-r--r--Bugzilla/WebService/Constants.pm2
-rw-r--r--Bugzilla/WebService/Util.pm12
-rwxr-xr-xattachment.cgi1
-rwxr-xr-xchart.cgi11
-rw-r--r--docs/en/Makefile2
-rw-r--r--docs/en/rst/api/core/v1/attachment.rst6
-rw-r--r--docs/en/rst/api/index.rst3
-rw-r--r--docs/en/rst/conf.py11
-rw-r--r--docs/en/rst/index.rst17
-rw-r--r--docs/en/rst/installing/apache-windows.rst4
-rw-r--r--docs/en/rst/installing/db_server.rst18
-rw-r--r--docs/en/rst/installing/iis.rst3
-rw-r--r--docs/en/rst/installing/index.rst2
-rw-r--r--docs/en/rst/installing/linux.rst3
-rw-r--r--docs/en/rst/installing/optional-post-install-config.rst42
-rw-r--r--docs/en/rst/installing/quick-start.rst28
-rw-r--r--docs/en/rst/installing/web_server.rst13
-rw-r--r--docs/en/rst/installing/windows.rst2
-rw-r--r--docs/en/rst/integrating/apis.rst13
-rwxr-xr-xdocs/makedocs.pl10
-rwxr-xr-xeditclassifications.cgi2
-rwxr-xr-xeditflagtypes.cgi23
-rwxr-xr-xeditgroups.cgi18
-rwxr-xr-xeditkeywords.cgi18
-rw-r--r--js/productform.js51
-rwxr-xr-xprocess_bug.cgi7
-rwxr-xr-xrequest.cgi19
-rwxr-xr-xshowdependencygraph.cgi11
-rw-r--r--taskgraph.json78
-rw-r--r--template/en/default/account/auth/login-small.html.tmpl48
-rw-r--r--template/en/default/admin/flag-type/edit.html.tmpl4
-rw-r--r--template/en/default/admin/flag-type/list.html.tmpl4
-rw-r--r--template/en/default/global/code-error.html.tmpl10
-rw-r--r--template/en/default/global/docslinks.html.tmpl18
-rw-r--r--template/en/default/global/header.html.tmpl3
-rw-r--r--template/en/default/global/js-products.html.tmpl5
-rw-r--r--template/en/default/global/messages.html.tmpl11
-rw-r--r--template/en/default/global/tabs.html.tmpl2
-rw-r--r--template/en/default/global/user-error.html.tmpl136
-rw-r--r--template/en/default/pages/release-notes.html.tmpl34
-rw-r--r--template/en/default/request/queue.html.tmpl31
-rw-r--r--template/en/default/search/form.html.tmpl2
59 files changed, 463 insertions, 452 deletions
diff --git a/.bzrignore b/.bzrignore
index f30e8f9ae..4b27e5744 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1,4 +1,3 @@
-.htaccess
/lib/*
/template/en/custom
/docs/en/html
diff --git a/.gitignore b/.gitignore
index f30e8f9ae..ba98f70c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-.htaccess
+/**/.htaccess
/lib/*
/template/en/custom
/docs/en/html
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 01ecfcfb4..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-language: perl
-
-addons:
- postgresql: "9.1"
-
-perl:
- - 5.10
- - 5.12
- - 5.14
- - 5.16
-
-env:
- - TEST_SUITE=sanity
- - TEST_SUITE=docs
- - TEST_SUITE=webservices DB=mysql
- - TEST_SUITE=selenium DB=mysql
- - TEST_SUITE=webservices DB=pg
- - TEST_SUITE=selenium DB=pg
-
-matrix:
- exclude:
- - perl: 5.10
- env: TEST_SUITE=docs
- - perl: 5.12
- env: TEST_SUITE=docs
- - perl: 5.14
- env: TEST_SUITE=docs
- - perl: 5.10
- env: TEST_SUITE=webservices DB=mysql
- - perl: 5.10
- env: TEST_SUITE=webservices DB=pg
- - perl: 5.10
- env: TEST_SUITE=selenium DB=mysql
- - perl: 5.10
- env: TEST_SUITE=selenium DB=pg
- - perl: 5.12
- env: TEST_SUITE=webservices DB=mysql
- - perl: 5.12
- env: TEST_SUITE=webservices DB=pg
- - perl: 5.12
- env: TEST_SUITE=selenium DB=mysql
- - perl: 5.12
- env: TEST_SUITE=selenium DB=pg
- - perl: 5.14
- env: TEST_SUITE=webservices DB=mysql
- - perl: 5.14
- env: TEST_SUITE=webservices DB=pg
- - perl: 5.14
- env: TEST_SUITE=selenium DB=mysql
- - perl: 5.14
- env: TEST_SUITE=selenium DB=pg
-
-before_install:
- - git clone https://github.com/bugzilla/qa.git -b 5.0 qa
-
-install: true
-
-before_script:
- - mysql -u root mysql -e "GRANT ALL PRIVILEGES ON *.* TO bugs@localhost IDENTIFIED BY 'bugs'; FLUSH PRIVILEGES;"
- - psql -c "CREATE USER bugs WITH PASSWORD 'bugs' CREATEDB;" -U postgres
-
-script: ./qa/travis.sh
-
-after_failure:
- - sudo cat /var/log/apache2/error.log
-
-notifications:
- irc:
- channels:
- - "irc.mozilla.org#qa-bugzilla"
- - "irc.mozilla.org#bugzilla"
- template:
- - "Bugzilla %{branch} : %{author} : %{message}"
- - "Commit Message : %{commit_message}"
- - "Commit Link : %{compare_url}"
- - "Build Link : %{build_url}"
- on_success: change
- on_failure: always
diff --git a/Bugzilla.pm b/Bugzilla.pm
index aa78f1483..e4772e08b 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -87,7 +87,7 @@ sub init_page {
# On Windows, these paths are tainted, preventing
# File::Spec::Win32->tmpdir from using them. But we need
# a place to temporary store attachments which are uploaded.
- foreach my $temp (qw(TMPDIR TMP TEMP)) {
+ foreach my $temp (qw(TMPDIR TMP TEMP WINDIR)) {
trick_taint($ENV{$temp}) if $ENV{$temp};
}
# Some DLLs used by Strawberry Perl are also in c\bin,
@@ -96,6 +96,7 @@ sub init_page {
my $c_path = $path = dirname($^X);
$c_path =~ s/\bperl\b(?=\\bin)/c/;
$path .= ";$c_path";
+ trick_taint($path);
}
}
# Some environment variables are not taint safe
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index 932fb6b17..33183797b 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -865,6 +865,8 @@ sub create {
sub run_create_validators {
my ($class, $params) = @_;
+ $params->{submitter_id} = Bugzilla->user->id || ThrowUserError('invalid_user');
+
# Let's validate the attachment content first as it may
# alter some other attachment attributes.
$params->{data} = $class->_check_data($params);
@@ -872,7 +874,6 @@ sub run_create_validators {
$params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$params->{modification_time} = $params->{creation_ts};
- $params->{submitter_id} = Bugzilla->user->id || ThrowUserError('invalid_user');
return $params;
}
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 34bf95ff7..8b4493f85 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -305,15 +305,15 @@ sub new {
my $param = shift;
# Remove leading "#" mark if we've just been passed an id.
- if (!ref $param && $param =~ /^#(\d+)$/) {
+ if (!ref $param && $param =~ /^#([0-9]+)$/) {
$param = $1;
}
# If we get something that looks like a word (not a number),
# make it the "name" param.
if (!defined $param
- || (!ref($param) && $param !~ /^\d+$/)
- || (ref($param) && $param->{id} !~ /^\d+$/))
+ || (!ref($param) && $param !~ /^[0-9]+$/)
+ || (ref($param) && $param->{id} !~ /^[0-9]+$/))
{
if ($param) {
my $alias = ref($param) ? $param->{id} : $param;
@@ -556,15 +556,15 @@ sub _extract_bug_ids {
my $s = $comment->already_wrapped ? qr/\s/ : qr/\h/;
my $text = $comment->body;
# Full bug links
- push @bug_ids, $text =~ /\b$urlbase_re\Qshow_bug.cgi?id=\E(\d+)(?:\#c\d+)?/g;
+ push @bug_ids, $text =~ /\b$urlbase_re\Qshow_bug.cgi?id=\E([0-9]+)(?:\#c[0-9]+)?/g;
# bug X
- my $bug_re = qr/\Q$bug_word\E$s*\#?$s*(\d+)/i;
+ my $bug_re = qr/\Q$bug_word\E$s*\#?$s*([0-9]+)/i;
push @bug_ids, $text =~ /\b$bug_re/g;
# bugs X, Y, Z
- my $bugs_re = qr/\Q$bugs_word\E$s*\#?$s*(\d+)(?:$s*,$s*\#?$s*(\d+))+/i;
+ my $bugs_re = qr/\Q$bugs_word\E$s*\#?$s*([0-9]+)(?:$s*,$s*\#?$s*([0-9]+))+/i;
push @bug_ids, $text =~ /\b$bugs_re/g;
# Old duplicate markers
- push @bug_ids, $text =~ /(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ )(\d+)(?=\ \*\*\*\Z)/;
+ push @bug_ids, $text =~ /(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ )([0-9]+)(?=\ \*\*\*\Z)/;
}
# Make sure to filter invalid bug IDs.
@bug_ids = grep { $_ < MAX_INT_32 } @bug_ids;
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index d4a1597ab..110a1ffaf 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -169,8 +169,8 @@ sub Send {
}
if ($change->{field_name} eq 'dependson' || $change->{field_name} eq 'blocked') {
- push @referenced_bug_ids, split(/[\s,]+/, $change->{old});
- push @referenced_bug_ids, split(/[\s,]+/, $change->{new});
+ push @referenced_bug_ids, split(/[\s,]+/, $change->{old} // '');
+ push @referenced_bug_ids, split(/[\s,]+/, $change->{new} // '');
}
}
diff --git a/Bugzilla/BugUrl.pm b/Bugzilla/BugUrl.pm
index 285441807..1fe8b3d0c 100644
--- a/Bugzilla/BugUrl.pm
+++ b/Bugzilla/BugUrl.pm
@@ -109,8 +109,9 @@ sub _do_list_select {
my $objects = $class->SUPER::_do_list_select(@_);
foreach my $object (@$objects) {
- eval "use " . $object->class; die $@ if $@;
- bless $object, $object->class;
+ eval "use " . $object->class;
+ # If the class cannot be loaded, then we build a generic object.
+ bless $object, ($@ ? 'Bugzilla::BugUrl' : $object->class);
}
return $objects
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 0b8a48697..44c089a20 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -66,7 +66,7 @@ sub new {
# else we will be redirected outside Bugzilla.
my $script_name = $self->script_name;
$path_info =~ s/^\Q$script_name\E//;
- if ($path_info) {
+ if ($script_name && $path_info) {
print $self->redirect($self->url(-path => 0, -query => 1));
}
}
@@ -283,7 +283,7 @@ sub close_standby_message {
print $self->multipart_end();
print $self->multipart_start(-type => $contenttype);
}
- else {
+ elsif (!$self->{_header_done}) {
print $self->header($contenttype);
}
}
@@ -356,6 +356,7 @@ sub header {
Bugzilla::Hook::process('cgi_headers',
{ cgi => $self, headers => \%headers }
);
+ $self->{_header_done} = 1;
return $self->SUPER::header(%headers) || "";
}
diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm
index 9bc0a4493..d5a6ece5d 100644
--- a/Bugzilla/Component.pm
+++ b/Bugzilla/Component.pm
@@ -148,7 +148,8 @@ sub remove_from_db {
$dbh->bz_start_transaction();
# Products must have at least one component.
- if (scalar(@{$self->product->components}) == 1) {
+ my @components = @{ $self->product->components };
+ if (scalar(@components) == 1) {
ThrowUserError('component_is_last', { comp => $self });
}
@@ -165,6 +166,8 @@ sub remove_from_db {
ThrowUserError('component_has_bugs', {nb => $self->bug_count});
}
}
+ # Update the list of components in the product object.
+ $self->product->{components} = [grep { $_->id != $self->id } @components];
$self->SUPER::remove_from_db();
$dbh->bz_commit_transaction();
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 16cb1b414..b15d9b5da 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -200,11 +200,11 @@ use Memoize;
# CONSTANTS
#
# Bugzilla version
-use constant BUGZILLA_VERSION => "5.0.2";
+use constant BUGZILLA_VERSION => "5.0.3";
# A base link to the current REST Documentation. We place it here
# as it will need to be updated to whatever the current release is.
-use constant REST_DOC => "http://www.bugzilla.org/docs/tip/en/html/api/";
+use constant REST_DOC => 'https://bugzilla.readthedocs.org/en/5.0/api/';
# Location of the remote and local XML files to track new releases.
use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml';
diff --git a/Bugzilla/DB/Schema/Mysql.pm b/Bugzilla/DB/Schema/Mysql.pm
index 0195fcb06..7ff8ade9f 100644
--- a/Bugzilla/DB/Schema/Mysql.pm
+++ b/Bugzilla/DB/Schema/Mysql.pm
@@ -316,7 +316,7 @@ sub column_info_to_column {
$default = 0 if $default =~ /^0\.0+$/;
# If we're not a number, we're a string and need to be
# quoted.
- $default = $dbh->quote($default) if !($default =~ /^(-)?(\d+)(.\d+)?$/);
+ $default = $dbh->quote($default) if !($default =~ /^(-)?([0-9]+)(\.[0-9]+)?$/);
$column->{DEFAULT} = $default;
}
}
diff --git a/Bugzilla/MIME.pm b/Bugzilla/MIME.pm
index 7b5843a78..8c6c141bb 100644
--- a/Bugzilla/MIME.pm
+++ b/Bugzilla/MIME.pm
@@ -13,9 +13,6 @@ use warnings;
use parent qw(Email::MIME);
-use Encode qw(encode);
-use Encode::MIME::Header;
-
sub new {
my ($class, $msg) = @_;
state $use_utf8 = Bugzilla->params->{'utf8'};
@@ -79,20 +76,12 @@ sub as_string {
# MIME-Version must be set otherwise some mailsystems ignore the charset
$self->header_set('MIME-Version', '1.0') if !$self->header('MIME-Version');
- # Encode the headers correctly in quoted-printable
+ # Encode the headers correctly.
foreach my $header ($self->header_names) {
my @values = $self->header($header);
- # We don't recode headers that happen multiple times.
- next if scalar(@values) > 1;
- if (my $value = $values[0]) {
- utf8::decode($value) unless $use_utf8 && utf8::is_utf8($value);
-
- # avoid excessive line wrapping done by Encode.
- local $Encode::Encoding{'MIME-Q'}->{'bpl'} = 998;
+ map { utf8::decode($_) if defined($_) && !utf8::is_utf8($_) } @values;
- my $encoded = encode('MIME-Q', $value);
- $self->header_set($header, $encoded);
- }
+ $self->header_str_set($header, @values);
}
# Ensure the character-set and encoding is set correctly on single part
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 0785a7e67..646f949f5 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -1628,7 +1628,8 @@ sub _special_parse_email {
my $email = trim($params->{"email$id"});
next if !$email;
my $type = $params->{"emailtype$id"} || 'anyexact';
- $type = "anyexact" if $type eq "exact";
+ # for backward compatibility
+ $type = "equals" if $type eq "exact";
my $or_clause = new Bugzilla::Search::Clause('OR');
foreach my $field (qw(assigned_to reporter cc qa_contact)) {
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index d5f5034fa..47acf58de 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -232,7 +232,7 @@ sub quoteUrls {
~<a href=\"mailto:$2\">$1$2</a>~igx;
# attachment links
- $text =~ s~\b(attachment$s*\#?$s*(\d+)(?:$s+\[details\])?)
+ $text =~ s~\b(attachment$s*\#?$s*([0-9]+)(?:$s+\[details\])?)
~($things[$count++] = get_attachment_link($2, $1, $user)) &&
("\x{FDD2}" . ($count-1) . "\x{FDD3}")
~egmxi;
@@ -245,9 +245,9 @@ sub quoteUrls {
# Also, we can't use $bug_re?$comment_re? because that will match the
# empty string
my $bug_word = template_var('terms')->{bug};
- my $bug_re = qr/\Q$bug_word\E$s*\#?$s*(\d+)/i;
+ my $bug_re = qr/\Q$bug_word\E$s*\#?$s*([0-9]+)/i;
my $comment_word = template_var('terms')->{comment};
- my $comment_re = qr/(?:\Q$comment_word\E|comment)$s*\#?$s*(\d+)/i;
+ my $comment_re = qr/(?:\Q$comment_word\E|comment)$s*\#?$s*([0-9]+)/i;
$text =~ s~\b($bug_re(?:$s*,?$s*$comment_re)?|$comment_re)
~ # We have several choices. $1 here is the link, and $2-4 are set
# depending on which part matched
@@ -261,29 +261,29 @@ sub quoteUrls {
my $bugs_word = template_var('terms')->{bugs};
my $bugs_re = qr/\Q$bugs_word\E$s*\#?$s*
- \d+(?:$s*,$s*\#?$s*\d+)+/ix;
+ [0-9]+(?:$s*,$s*\#?$s*[0-9]+)+/ix;
$text =~ s{($bugs_re)}{
my $match = $1;
- $match =~ s/((?:#$s*)?(\d+))/get_bug_link($2, $1);/eg;
+ $match =~ s/((?:#$s*)?([0-9]+))/get_bug_link($2, $1);/eg;
$match;
}eg;
my $comments_word = template_var('terms')->{comments};
my $comments_re = qr/(?:comments|\Q$comments_word\E)$s*\#?$s*
- \d+(?:$s*,$s*\#?$s*\d+)+/ix;
+ [0-9]+(?:$s*,$s*\#?$s*[0-9]+)+/ix;
$text =~ s{($comments_re)}{
my $match = $1;
- $match =~ s|((?:#$s*)?(\d+))|<a href="$current_bugurl#c$2">$1</a>|g;
+ $match =~ s|((?:#$s*)?([0-9]+))|<a href="$current_bugurl#c$2">$1</a>|g;
$match;
}eg;
# Old duplicate markers. These don't use $bug_word because they are old
# and were never customizable.
$text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ )
- (\d+)
+ ([0-9]+)
(?=\ \*\*\*\Z)
~get_bug_link($1, $1, { user => $user })
~egmx;
@@ -874,12 +874,13 @@ sub create {
},
# In CSV, quotes are doubled, and any value containing a quote or a
- # comma is enclosed in quotes. If a field starts with an equals
- # sign, it is proceed by a space.
+ # comma is enclosed in quotes.
+ # If a field starts with either "=", "+", "-" or "@", it is preceded
+ # by a space to prevent stupid formula execution from Excel & co.
csv => sub
{
my ($var) = @_;
- $var = ' ' . $var if substr($var, 0, 1) eq '=';
+ $var = ' ' . $var if $var =~ /^[+=@-]/;
# backslash is not special to CSV, but it can be used to confuse some browsers...
# so we do not allow it to happen. We only do this for logged-in users.
$var =~ s/\\/\x{FF3C}/g if Bugzilla->user->id;
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm
index 037b38648..bbf4261ca 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -49,13 +49,13 @@ sub trick_taint {
}
sub detaint_natural {
- my $match = $_[0] =~ /^(\d+)$/;
+ my $match = $_[0] =~ /^([0-9]+)$/;
$_[0] = $match ? int($1) : undef;
return (defined($_[0]));
}
sub detaint_signed {
- my $match = $_[0] =~ /^([-+]?\d+)$/;
+ my $match = $_[0] =~ /^([-+]?[0-9]+)$/;
# The "int()" call removes any leading plus sign.
$_[0] = $match ? int($1) : undef;
return (defined($_[0]));
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index c99651201..b07d3cb01 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -1133,6 +1133,10 @@ sub update_comment_tags {
{ function => 'Bug.update_comment_tags',
param => 'comment_id' });
+ ThrowCodeError('param_integer_required', { function => 'Bug.update_comment_tags',
+ param => 'comment_id' })
+ unless $comment_id =~ /^[0-9]+$/;
+
my $comment = Bugzilla::Comment->new($comment_id)
|| return [];
$comment->bug->check_is_visible();
diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm
index 0bdd3517e..557a996f8 100644
--- a/Bugzilla/WebService/Constants.pm
+++ b/Bugzilla/WebService/Constants.pm
@@ -67,6 +67,8 @@ use constant WS_ERROR_CODE => {
number_too_large => 54,
number_too_small => 55,
illegal_date => 56,
+ param_integer_required => 57,
+ param_scalar_array_required => 58,
# Bug errors usually occupy the 100-200 range.
improper_bug_id_field_value => 100,
bug_id_does_not_exist => 101,
diff --git a/Bugzilla/WebService/Util.pm b/Bugzilla/WebService/Util.pm
index 26a6ebbb0..a879c0e0d 100644
--- a/Bugzilla/WebService/Util.pm
+++ b/Bugzilla/WebService/Util.pm
@@ -16,6 +16,7 @@ use Bugzilla::FlagType;
use Bugzilla::Error;
use Storable qw(dclone);
+use List::MoreUtils qw(any none);
use parent qw(Exporter);
@@ -220,14 +221,19 @@ sub validate {
# $params should be.
return ($self, undef) if (defined $params and !ref $params);
+ my @id_params = qw(ids comment_ids);
# If @keys is not empty then we convert any named
# parameters that have scalar values to arrayrefs
# that match.
foreach my $key (@keys) {
if (exists $params->{$key}) {
- $params->{$key} = ref $params->{$key}
- ? $params->{$key}
- : [ $params->{$key} ];
+ $params->{$key} = [ $params->{$key} ] unless ref $params->{$key};
+
+ if (any { $key eq $_ } @id_params) {
+ my $ids = $params->{$key};
+ ThrowCodeError('param_scalar_array_required', { param => $key })
+ unless ref($ids) eq 'ARRAY' && none { ref $_ } @$ids;
+ }
}
}
diff --git a/attachment.cgi b/attachment.cgi
index c16e0f012..9566be868 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -26,6 +26,7 @@ use Bugzilla::Attachment::PatchReader;
use Bugzilla::Token;
use Encode qw(encode find_encoding);
+use Encode::MIME::Header; # Required to alter Encode::Encoding{'MIME-Q'}.
# For most scripts we don't make $cgi and $template global variables. But
# when preparing Bugzilla for mod_perl, this script used these
diff --git a/chart.cgi b/chart.cgi
index 00b0b8ee5..c1bafa117 100755
--- a/chart.cgi
+++ b/chart.cgi
@@ -305,16 +305,15 @@ sub plot {
$vars->{'chart'} = new Bugzilla::Chart($cgi);
my $format = $template->get_format("reports/chart", "", scalar($cgi->param('ctype')));
+ $format->{'ctype'} = 'text/html' if $cgi->param('debug');
- # Debugging PNGs is a pain; we need to be able to see the error messages
- if ($cgi->param('debug')) {
- print $cgi->header();
- $vars->{'chart'}->dump();
- }
-
+ $cgi->set_dated_content_disp('inline', 'chart', $format->{extension});
print $cgi->header($format->{'ctype'});
disable_utf8() if ($format->{'ctype'} =~ /^image\//);
+ # Debugging PNGs is a pain; we need to be able to see the error messages
+ $vars->{'chart'}->dump() if $cgi->param('debug');
+
$template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
}
diff --git a/docs/en/Makefile b/docs/en/Makefile
index fc9af11e0..8c3621f31 100644
--- a/docs/en/Makefile
+++ b/docs/en/Makefile
@@ -39,7 +39,7 @@ help:
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
- -rm -rf $(BUILDDIR)/*
+ find $(BUILDDIR) -maxdepth 1 -type d -not -name rst -not -name images -not -name . -exec rm -rf {} \;
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
diff --git a/docs/en/rst/api/core/v1/attachment.rst b/docs/en/rst/api/core/v1/attachment.rst
index f89b6c23e..70e4c25fd 100644
--- a/docs/en/rst/api/core/v1/attachment.rst
+++ b/docs/en/rst/api/core/v1/attachment.rst
@@ -139,7 +139,7 @@ To create attachment on a current bug:
"comment" : "This is a new attachment comment",
"summary" : "Test Attachment",
"content_type" : "text/plain",
- "data" : "(Some patch content)",
+ "data" : "(Some base64 encoded content)",
"file_name" : "test_attachment.patch",
"obsoletes" : [],
"is_private" : false,
@@ -164,9 +164,7 @@ name type description
**ids** array The IDs or aliases of bugs that you want to add this
attachment to. The same attachment and comment will be
added to all these bugs.
-**data** string The content of the attachment. If the content of the
- attachment is not ASCII text such as
- ``application/octet-stream`` you must encode it in
+**data** base64 The content of the attachment. You must encode it in
base64 using an appropriate client library such as
``MIME::Base64`` for Perl.
**file_name** string The "file name" that will be displayed in the UI for
diff --git a/docs/en/rst/api/index.rst b/docs/en/rst/api/index.rst
index 45055eba1..840bcadd1 100644
--- a/docs/en/rst/api/index.rst
+++ b/docs/en/rst/api/index.rst
@@ -4,7 +4,8 @@ WebService API Reference
========================
This Bugzilla installation has the following WebService APIs available
-(as of the last time you compiled the documentation):
+(as of the last time you compiled the documentation). Documentation for
+the deprecated :ref:`XML-RPC and JSON-RPC APIs <api-list>` is also available.
.. toctree::
:glob:
diff --git a/docs/en/rst/conf.py b/docs/en/rst/conf.py
index 3330ca76d..a758fd248 100644
--- a/docs/en/rst/conf.py
+++ b/docs/en/rst/conf.py
@@ -383,4 +383,13 @@ pdf_fit_background_mode = 'scale'
# Temporary highlighting of TODO items
todo_include_todos = False
-extlinks = {'bug': ('https://bugzilla.mozilla.org/show_bug.cgi?id=%s', 'bug ')}
+# The readthedocs.org website cannot access POD.
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+if on_rtd:
+ base_api_url = 'https://www.bugzilla.org/docs/5.0/en/html/api/'
+else:
+ base_api_url = '../integrating/api/'
+
+extlinks = {'bug': ('https://bugzilla.mozilla.org/show_bug.cgi?id=%s', 'bug '),
+ 'api': (base_api_url + '%s', '')}
diff --git a/docs/en/rst/index.rst b/docs/en/rst/index.rst
index b877920c6..8f6b61243 100644
--- a/docs/en/rst/index.rst
+++ b/docs/en/rst/index.rst
@@ -12,20 +12,3 @@ Bugzilla Documentation
administering/index
integrating/index
api/index
-
-.. toctree::
- :hidden:
-
- installing/mysql
- installing/postgresql
- installing/oracle
- installing/sqlite
-
-.. toctree::
- :hidden:
-
- installing/apache
- installing/apache-windows
- installing/iis
-
-.. todolist::
diff --git a/docs/en/rst/installing/apache-windows.rst b/docs/en/rst/installing/apache-windows.rst
index fca8ef5eb..c119e1b13 100644
--- a/docs/en/rst/installing/apache-windows.rst
+++ b/docs/en/rst/installing/apache-windows.rst
@@ -1,7 +1,7 @@
.. _apache-windows:
-Apache
-######
+Apache on Windows
+#################
Bugzilla supports all versions of Apache 2.2.x and 2.4.x.
diff --git a/docs/en/rst/installing/db_server.rst b/docs/en/rst/installing/db_server.rst
new file mode 100644
index 000000000..8a7d89633
--- /dev/null
+++ b/docs/en/rst/installing/db_server.rst
@@ -0,0 +1,18 @@
+.. _db_server:
+
+Database Server
+###############
+
+Bugzilla requires a database to store its data. We recommend either MySQL or
+PostgreSQL for production installations. Oracle 10 should work fine, but very
+little or no testing has been done with Oracle 11 and 12. SQLite is easy to
+configure but, due to its limitations, it should only be used for testing
+purposes and very small installations.
+
+.. toctree::
+ :maxdepth: 1
+
+ mysql
+ postgresql
+ oracle
+ sqlite
diff --git a/docs/en/rst/installing/iis.rst b/docs/en/rst/installing/iis.rst
index 1670db5f5..320b8f73c 100644
--- a/docs/en/rst/installing/iis.rst
+++ b/docs/en/rst/installing/iis.rst
@@ -4,7 +4,8 @@ Microsoft IIS
#############
Bugzilla works with IIS as a normal CGI application. These instructions assume
-that you are using Windows 7. Procedures for other versions are probably similar.
+that you are using Windows 7 or Windows 10. Procedures for other versions are
+probably similar.
Begin by starting Internet Information Services (IIS) Manager.
:guilabel:`Start` --> :guilabel:`Administrators Tools` -->
diff --git a/docs/en/rst/installing/index.rst b/docs/en/rst/installing/index.rst
index 91a81bede..06d027680 100644
--- a/docs/en/rst/installing/index.rst
+++ b/docs/en/rst/installing/index.rst
@@ -25,6 +25,8 @@ case, you may want to read the :ref:`Quick Start instructions <quick-start>`.
linux
windows
mac-os-x
+ web_server
+ db_server
essential-post-install-config
optional-post-install-config
migrating
diff --git a/docs/en/rst/installing/linux.rst b/docs/en/rst/installing/linux.rst
index ff4258e6a..22d0bf735 100644
--- a/docs/en/rst/installing/linux.rst
+++ b/docs/en/rst/installing/linux.rst
@@ -48,8 +48,7 @@ graphviz patchutils gcc 'perl(Apache2::SizeLimit)' 'perl(Authen::Radius)'
'perl(Authen::SASL)' 'perl(Cache::Memcached)' 'perl(CGI)' 'perl(Chart::Lines)'
'perl(Daemon::Generic)' 'perl(Date::Format)' 'perl(DateTime)'
'perl(DateTime::TimeZone)' 'perl(DBI)' 'perl(Digest::SHA)' 'perl(Email::MIME)'
-'perl(Email::MIME::Attachment::Stripper)' 'perl(Email::Reply)'
-'perl(Email::Sender)' 'perl(Encode)' 'perl(Encode::Detect)'
+'perl(Email::Reply)' 'perl(Email::Sender)' 'perl(Encode)' 'perl(Encode::Detect)'
'perl(File::MimeInfo::Magic)' 'perl(File::Slurp)' 'perl(GD)' 'perl(GD::Graph)'
'perl(GD::Text)' 'perl(HTML::FormatText::WithLinks)' 'perl(HTML::Parser)'
'perl(HTML::Scrubber)' 'perl(IO::Scalar)' 'perl(JSON::RPC)' 'perl(JSON::XS)'
diff --git a/docs/en/rst/installing/optional-post-install-config.rst b/docs/en/rst/installing/optional-post-install-config.rst
index 91d5245d1..accc48888 100644
--- a/docs/en/rst/installing/optional-post-install-config.rst
+++ b/docs/en/rst/installing/optional-post-install-config.rst
@@ -115,7 +115,7 @@ Dependency Graphs
=================
Bugzilla can draw graphs of the dependencies (depends on/blocks relationships)
-between bugs, if you install a package called :file:`dot`.
+between bugs, if you install a package called :file:`graphviz`.
Linux
-----
@@ -129,8 +129,7 @@ Windows
Download and install Graphviz from
`the Graphviz website <http://www.graphviz.org/Download_windows.php>`_. Put
the complete path to :file:`dot.exe` in the :param:`webdotbase` parameter,
-using forward slashes as path separators. E.g.
-:paramval:`C:/Program Files/ATT/Graphviz/bin/dot.exe`.
+e.g. :paramval:`C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe`.
Documentation
=============
@@ -139,16 +138,37 @@ Bugzilla has extensive documentation and help, written in
`reStructured Text <http://sphinx-doc.org/rest.html>`_
format. A generic compiled copy exists on
`bugzilla.readthedocs.org <https://bugzilla.readthedocs.org/>`_, and
-:guilabel:`Help` links point to it by default. If you want to build and use a
-local copy of the documentation, perhaps because you have added Bugzilla
+:guilabel:`Help` links point to it by default. You can also build and use
+a local copy of the documentation, for instance because you have added Bugzilla
extensions which come with documentation, or because your users don't have
-Internet access from their machines, then:
-
-* Install `Sphinx <http://sphinx-doc.org/>`_
- (:file:`python-sphinx` package on Debian/Ubuntu)
-
-Then run :command:`docs/makedocs.pl` in your Bugzilla directory.
+Internet access from their machines.
Bugzilla will automatically detect that you've compiled the documentation
and link to it in preference to the copy on the Internet. Don't forget to
recompile it when you upgrade Bugzilla or install new extensions.
+
+Linux
+-----
+
+* Install `Sphinx <http://sphinx-doc.org/>`_. Most Linux distros have it in
+ a package named :file:`python-sphinx`.
+
+* Then go to your Bugzilla directory and run:
+
+ :command:`docs/makedocs.pl`
+
+Windows
+-------
+
+* Download and install `Python <https://www.python.org/downloads/>`_.
+ Both Python 2.7 and 3.x will work. Adding :file:`python` to the :param:`PATH`
+ environment variable, as suggested by the Python installer, will make your
+ life easier.
+
+* Install `Sphinx <http://sphinx-doc.org/>`_. Run :command:`cmd.exe` and type:
+
+ :command:`pip install sphinx`
+
+* Then go to your :file:`C:\\bugzilla\\docs` directory and run:
+
+ :command:`makedocs.pl`
diff --git a/docs/en/rst/installing/quick-start.rst b/docs/en/rst/installing/quick-start.rst
index c2da8da23..64a88e55b 100644
--- a/docs/en/rst/installing/quick-start.rst
+++ b/docs/en/rst/installing/quick-start.rst
@@ -5,8 +5,8 @@ Quick Start (Ubuntu Linux 14.04)
This quick start guide makes installing Bugzilla as simple as possible for
those who are able to choose their environment. It creates a system using
-Ubuntu Linux 14.04 LTS, Apache and MySQL, and installs Bugzilla as the default
-home page. It requires a little familiarity with Linux and the command line.
+Ubuntu Linux 14.04 LTS, Apache and MySQL. It requires a little familiarity
+with Linux and the command line.
Obtain Your Hardware
====================
@@ -62,17 +62,13 @@ Download Bugzilla
Get it from our Git repository:
-:command:`cd /var/www`
-
-:command:`rm -rf html`
+:command:`cd /var/www/html`
-:command:`git clone --branch release-X.X-stable https://git.mozilla.org/bugzilla/bugzilla html`
+:command:`git clone --branch release-X.X-stable https://git.mozilla.org/bugzilla/bugzilla bugzilla`
(where "X.X" is the 2-digit version number of the stable release of Bugzilla
-that you want - e.g. 4.4)
+that you want - e.g. 5.0)
-:command:`cd html`
-
Configure MySQL
===============
@@ -113,7 +109,7 @@ Paste in the following and save:
ServerName localhost
- <Directory /var/www/html>
+ <Directory /var/www/html/bugzilla>
AddHandler cgi-script .cgi
Options +ExecCGI
DirectoryIndex index.cgi index.html
@@ -135,7 +131,7 @@ generates a config file (called :file:`localconfig`) for the database
access information, and the second time (step 10)
it uses the info you put in the config file to set up the database.
-:command:`cd /var/www/html`
+:command:`cd /var/www/html/bugzilla`
:command:`./checksetup.pl`
@@ -164,7 +160,7 @@ Write down the email address and password you set.
Test Server
===========
-:command:`./testserver.pl http://localhost/`
+:command:`./testserver.pl http://localhost/bugzilla`
All the tests should pass. You will get warnings about deprecation from
the ``Chart::Base`` Perl module; just ignore those.
@@ -178,7 +174,7 @@ Access Via Web Browser
Access the front page:
-:command:`lynx http://localhost/`
+:command:`lynx http://localhost/bugzilla`
It's not really possible to use Bugzilla for real through Lynx, but you
can view the front page to validate visually that it's up and running.
@@ -186,8 +182,8 @@ can view the front page to validate visually that it's up and running.
You might well need to configure your DNS such that the server has, and
is reachable by, a name rather than IP address. Doing so is out of scope
of this document. In the mean time, it is available on your local network
-at ``http://<ip address>/``, where ``<ip address>`` is (unless you have
-a complex network setup) the "inet addr" value displayed when you run
+at ``http://<ip address>/bugzilla``, where ``<ip address>`` is (unless you
+have a complex network setup) the "inet addr" value displayed when you run
:command:`ifconfig eth0`.
Configure Bugzilla
@@ -201,7 +197,7 @@ Click the :guilabel:`Parameters` link on the page it gives you, and set
the following parameters in the :guilabel:`Required Settings` section:
* :param:`urlbase`:
- :paramval:`http://<servername>/` or :paramval:`http://<ip address>/`
+ :paramval:`http://<servername>/bugzilla/` or :paramval:`http://<ip address>/bugzilla/`
Click :guilabel:`Save Changes` at the bottom of the page.
diff --git a/docs/en/rst/installing/web_server.rst b/docs/en/rst/installing/web_server.rst
new file mode 100644
index 000000000..42f9a00b7
--- /dev/null
+++ b/docs/en/rst/installing/web_server.rst
@@ -0,0 +1,13 @@
+.. _web_server:
+
+Web Server
+##########
+
+Bugzilla requires a web server to run CGI scripts. It supports the following:
+
+.. toctree::
+ :maxdepth: 1
+
+ apache
+ apache-windows
+ iis
diff --git a/docs/en/rst/installing/windows.rst b/docs/en/rst/installing/windows.rst
index ef1a1f6f4..adc1728c6 100644
--- a/docs/en/rst/installing/windows.rst
+++ b/docs/en/rst/installing/windows.rst
@@ -89,6 +89,7 @@ Install the following mandatory modules with:
* JSON-XS
* Win32
* Win32-API
+* DateTime-TimeZone-Local-Win32
The following modules enable various optional Bugzilla features; try and
install them, but don't worry too much to begin with if you can't get them
@@ -125,7 +126,6 @@ installed:
* IO-stringy
* Cache-Memcached
* File-Copy-Recursive
-* GraphViz
If you are using Strawberry Perl, you should use the :file:`install-module.pl`
script to install modules, which is the same script used for Linux. Some of
diff --git a/docs/en/rst/integrating/apis.rst b/docs/en/rst/integrating/apis.rst
index 6067c12df..54ee3273a 100644
--- a/docs/en/rst/integrating/apis.rst
+++ b/docs/en/rst/integrating/apis.rst
@@ -12,6 +12,13 @@ coming soon.
The APIs currently available are as follows:
+Core Module API
+===============
+
+Most of the core Bugzilla modules have extensive documentation inside the modules
+themselves. You can view the :api:`POD documentation <index.html>` to help with
+using the core modules in your extensions.
+
Ad-Hoc APIs
===========
@@ -23,8 +30,7 @@ to alternate data formats where they are available.
XML-RPC
=======
-Bugzilla has an `XML-RPC API
-<http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Server/XMLRPC.html>`_.
+Bugzilla has an :api:`XML-RPC API <Bugzilla/WebService/Server/XMLRPC.html>`.
This will receive no further updates and will be removed in a future version
of Bugzilla.
@@ -33,8 +39,7 @@ Endpoint: :file:`/xmlrpc.cgi`
JSON-RPC
========
-Bugzilla has a `JSON-RPC API
-<http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Server/JSONRPC.html>`_.
+Bugzilla has a :api:`JSON-RPC API <Bugzilla/WebService/Server/JSONRPC.html>`.
This will receive no further updates and will be removed in a future version
of Bugzilla.
diff --git a/docs/makedocs.pl b/docs/makedocs.pl
index 6f353dc6d..36ffc45b5 100755
--- a/docs/makedocs.pl
+++ b/docs/makedocs.pl
@@ -35,7 +35,7 @@ use lib qw(.. ../lib lib);
use Cwd;
use File::Copy::Recursive qw(rcopy);
use File::Find;
-use File::Path qw(rmtree);
+use File::Path qw(rmtree make_path);
use File::Which qw(which);
use Pod::Simple;
@@ -52,7 +52,6 @@ sub MakeDocs {
my ($name, $cmdline) = @_;
say "Creating $name documentation ..." if defined $name;
- say "make $cmdline\n";
system('make', $cmdline) == 0
or $error_found = 1;
print "\n";
@@ -83,12 +82,11 @@ END_HTML
$converter->contents_page_start($contents_start);
$converter->contents_page_end("</body></html>");
- $converter->add_css('./../../../style.css');
+ $converter->add_css('./../../../../style.css');
$converter->javascript_flurry(0);
$converter->css_flurry(0);
- mkdir("html");
- mkdir("html/api");
- $converter->batch_convert(['../../'], 'html/api/');
+ make_path('html/integrating/api');
+ $converter->batch_convert(['../../'], 'html/integrating/api');
print "\n";
}
diff --git a/editclassifications.cgi b/editclassifications.cgi
index ea4b139da..640b8b8cd 100755
--- a/editclassifications.cgi
+++ b/editclassifications.cgi
@@ -27,7 +27,6 @@ local our $vars = {};
sub LoadTemplate {
my $action = shift;
- my $cgi = Bugzilla->cgi;
my $template = Bugzilla->template;
$vars->{'classifications'} = [Bugzilla::Classification->get_all]
@@ -38,7 +37,6 @@ sub LoadTemplate {
$action =~ /(\w+)/;
$action = $1;
- print $cgi->header();
$template->process("admin/classifications/$action.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
diff --git a/editflagtypes.cgi b/editflagtypes.cgi
index d848d250a..d0b9443b5 100755
--- a/editflagtypes.cgi
+++ b/editflagtypes.cgi
@@ -436,17 +436,30 @@ sub get_products_and_components {
my @products;
if ($user->in_group('editcomponents')) {
- @products = Bugzilla::Product->get_all;
+ if (Bugzilla->params->{useclassification}) {
+ # We want products grouped by classifications.
+ @products = map { @{ $_->products } } Bugzilla::Classification->get_all;
+ }
+ else {
+ @products = Bugzilla::Product->get_all;
+ }
}
else {
@products = @{$user->get_products_by_permission('editcomponents')};
+
+ if (Bugzilla->params->{useclassification}) {
+ my %class;
+ push(@{$class{$_->classification_id}}, $_) foreach @products;
+
+ # Let's sort the list by classifications.
+ @products = ();
+ push(@products, @{$class{$_->id}}) foreach Bugzilla::Classification->get_all;
+ }
}
- # We require all unique component names.
+
my %components;
foreach my $product (@products) {
- foreach my $component (@{$product->components}) {
- $components{$component->name} = 1;
- }
+ $components{$_->name} = 1 foreach @{$product->components};
}
$vars->{'products'} = \@products;
$vars->{'components'} = [sort(keys %components)];
diff --git a/editgroups.cgi b/editgroups.cgi
index 35989b954..f2c915556 100755
--- a/editgroups.cgi
+++ b/editgroups.cgi
@@ -135,8 +135,7 @@ sub get_current_and_available {
unless ($action) {
my @groups = Bugzilla::Group->get_all;
$vars->{'groups'} = \@groups;
-
- print $cgi->header();
+
$template->process("admin/groups/list.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -155,12 +154,10 @@ if ($action eq 'changeform') {
get_current_and_available($group, $vars);
$vars->{'group'} = $group;
- $vars->{'token'} = issue_session_token('edit_group');
+ $vars->{'token'} = issue_session_token('edit_group');
- print $cgi->header();
$template->process("admin/groups/edit.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
@@ -172,10 +169,9 @@ if ($action eq 'changeform') {
if ($action eq 'add') {
$vars->{'token'} = issue_session_token('add_group');
- print $cgi->header();
+
$template->process("admin/groups/create.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
@@ -204,7 +200,6 @@ if ($action eq 'new') {
get_current_and_available($group, $vars);
$vars->{'token'} = issue_session_token('edit_group');
- print $cgi->header();
$template->process("admin/groups/edit.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -228,10 +223,8 @@ if ($action eq 'del') {
$vars->{'group'} = $group;
$vars->{'token'} = issue_session_token('delete_group');
- print $cgi->header();
$template->process("admin/groups/delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
@@ -255,7 +248,6 @@ if ($action eq 'delete') {
$vars->{'message'} = 'group_deleted';
$vars->{'groups'} = [Bugzilla::Group->get_all];
- print $cgi->header();
$template->process("admin/groups/list.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -277,7 +269,6 @@ if ($action eq 'postchanges') {
$vars->{'changes'} = $changes;
$vars->{'token'} = issue_session_token('edit_group');
- print $cgi->header();
$template->process("admin/groups/edit.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -288,6 +279,7 @@ if ($action eq 'confirm_remove') {
$vars->{'group'} = $group;
$vars->{'regexp'} = CheckGroupRegexp($cgi->param('regexp'));
$vars->{'token'} = issue_session_token('remove_group_members');
+
$template->process('admin/groups/confirm-remove.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -326,10 +318,8 @@ if ($action eq 'remove_regexp') {
$vars->{'group'} = $group->name;
$vars->{'groups'} = [Bugzilla::Group->get_all];
- print $cgi->header();
$template->process("admin/groups/list.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
diff --git a/editkeywords.cgi b/editkeywords.cgi
index 41496f362..01f30dbed 100755
--- a/editkeywords.cgi
+++ b/editkeywords.cgi
@@ -24,10 +24,6 @@ my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template;
my $vars = {};
-#
-# Preliminary checks:
-#
-
my $user = Bugzilla->login(LOGIN_REQUIRED);
print $cgi->header();
@@ -47,22 +43,16 @@ $vars->{'action'} = $action;
if ($action eq "") {
$vars->{'keywords'} = Bugzilla::Keyword->get_all_with_bug_count();
- print $cgi->header();
$template->process("admin/keywords/list.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
-
if ($action eq 'add') {
$vars->{'token'} = issue_session_token('add_keyword');
- print $cgi->header();
-
$template->process("admin/keywords/create.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
-
exit;
}
@@ -79,8 +69,6 @@ if ($action eq 'new') {
delete_token($token);
- print $cgi->header();
-
$vars->{'message'} = 'keyword_created';
$vars->{'name'} = $keyword->name;
$vars->{'keywords'} = Bugzilla::Keyword->get_all_with_bug_count();
@@ -104,7 +92,6 @@ if ($action eq 'edit') {
$vars->{'keyword'} = $keyword;
$vars->{'token'} = issue_session_token('edit_keyword');
- print $cgi->header();
$template->process("admin/keywords/edit.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -128,8 +115,6 @@ if ($action eq 'update') {
delete_token($token);
- print $cgi->header();
-
$vars->{'message'} = 'keyword_updated';
$vars->{'keyword'} = $keyword;
$vars->{'changes'} = $changes;
@@ -147,7 +132,6 @@ if ($action eq 'del') {
$vars->{'keyword'} = $keyword;
$vars->{'token'} = issue_session_token('delete_keyword');
- print $cgi->header();
$template->process("admin/keywords/confirm-delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
@@ -162,8 +146,6 @@ if ($action eq 'delete') {
delete_token($token);
- print $cgi->header();
-
$vars->{'message'} = 'keyword_deleted';
$vars->{'keyword'} = $keyword;
$vars->{'keywords'} = Bugzilla::Keyword->get_all_with_bug_count();
diff --git a/js/productform.js b/js/productform.js
index d5e24d306..0f669aa26 100644
--- a/js/productform.js
+++ b/js/productform.js
@@ -10,16 +10,10 @@
// collection of javascript arrays containing strings.
/**
- * Reads the selected products and updates component, version and milestone
- * lists accordingly.
+ * Reads the selected products and updates the component list accordingly.
*
* @param product Select element that contains products.
- * @param component Select element that contains components. Can be null if
- * there is no such element to update.
- * @param version Select element that contains versions. Can be null if
- * there is no such element to update.
- * @param milestone Select element that contains milestones. Can be null if
- * there is no such element to update.
+ * @param component Select element that contains components.
* @param anyval Value to use for a special "Any" list item. Can be null
* to not use any. If used must and will be first item in
* the select element.
@@ -27,21 +21,15 @@
* @global cpts Array of arrays, indexed by product name. The subarrays
* contain a list of components to be fed to the respective
* select element.
- * @global vers Array of arrays, indexed by product name. The subarrays
- * contain a list of versions to be fed to the respective
- * select element.
- * @global tms Array of arrays, indexed by product name. The subarrays
- * contain a list of milestones to be fed to the respective
- * select element.
* @global first_load Boolean; true if this is the first time this page loads
* or false if not.
* @global last_sel Array that contains last list of products so we know what
* has changed, and optimize for additions.
*/
-function selectProduct(product, component, version, milestone, anyval) {
+function selectProduct(product, component, anyval) {
// This is to avoid handling events that occur before the form
// itself is ready, which could happen in buggy browsers.
- if (!product)
+ if (!product || !component)
return;
// Do nothing if no products are defined. This is to avoid the
@@ -78,15 +66,8 @@ function selectProduct(product, component, version, milestone, anyval) {
var findall = (product.selectedIndex == -1
|| (anyval != null && product.options[0].selected));
- if (useclassification) {
- // Update index based on the complete product array.
- sel = get_selection(product, findall, true, anyval);
- for (var i=0; i<sel.length; i++)
- sel[i] = prods[sel[i]];
- }
- else {
- sel = get_selection(product, findall, false, anyval);
- }
+ sel = get_selection(product, findall, false, anyval);
+
if (!findall) {
// Save sel for the next invocation of selectProduct().
var tmp = sel;
@@ -103,23 +84,9 @@ function selectProduct(product, component, version, milestone, anyval) {
}
// Do the actual fill/update.
- if (component) {
- var saved_cpts = get_selection(component, false, true, null);
- updateSelect(cpts, sel, component, merging, anyval);
- restoreSelection(component, saved_cpts);
- }
-
- if (version) {
- var saved_vers = get_selection(version, false, true, null);
- updateSelect(vers, sel, version, merging, anyval);
- restoreSelection(version, saved_vers);
- }
-
- if (milestone) {
- var saved_tms = get_selection(milestone, false, true, null);
- updateSelect(tms, sel, milestone, merging, anyval);
- restoreSelection(milestone, saved_tms);
- }
+ var saved_cpts = get_selection(component, false, true, null);
+ updateSelect(cpts, sel, component, merging, anyval);
+ restoreSelection(component, saved_cpts);
}
/**
diff --git a/process_bug.cgi b/process_bug.cgi
index 216dfbf1b..0b0ecd64e 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -305,9 +305,10 @@ if (defined $cgi->param('id')) {
my %is_private;
foreach my $field (grep(/^defined_isprivate/, $cgi->param())) {
- $field =~ /(\d+)$/;
- my $comment_id = $1;
- $is_private{$comment_id} = $cgi->param("isprivate_$comment_id");
+ if ($field =~ /(\d+)$/) {
+ my $comment_id = $1;
+ $is_private{$comment_id} = $cgi->param("isprivate_$comment_id");
+ }
}
$set_all_fields{comment_is_private} = \%is_private;
diff --git a/request.cgi b/request.cgi
index 566781a0c..347cb7a44 100755
--- a/request.cgi
+++ b/request.cgi
@@ -305,13 +305,22 @@ sub queue {
$vars->{'requests'} = \@requests;
$vars->{'types'} = \@types;
- my %components;
- foreach my $prod (@{$user->get_selectable_products}) {
- foreach my $comp (@{$prod->components}) {
- $components{$comp->name} = 1;
+ # This code is needed to populate the Product and Component select fields.
+ my ($products, %components);
+ if (Bugzilla->params->{useclassification}) {
+ foreach my $class (@{$user->get_selectable_classifications}) {
+ push @$products, @{$user->get_selectable_products($class->id)};
}
}
- $vars->{'components'} = [ sort { $a cmp $b } keys %components ];
+ else {
+ $products = $user->get_selectable_products;
+ }
+
+ foreach my $product (@$products) {
+ $components{$_->name} = 1 foreach @{$product->components};
+ }
+ $vars->{'products'} = $products;
+ $vars->{'components'} = [ sort keys %components ];
$vars->{'urlquerypart'} = $cgi->canonicalise_query('ctype');
diff --git a/showdependencygraph.cgi b/showdependencygraph.cgi
index 476df1e8e..7b2d2f55d 100755
--- a/showdependencygraph.cgi
+++ b/showdependencygraph.cgi
@@ -55,13 +55,19 @@ sub CreateImagemap {
$default = qq{<area alt="" shape="default" href="$1">\n};
}
- if ($line =~ /^rectangle \((.*),(.*)\) \((.*),(.*)\) (http[^ ]*) (\d+)(\\n.*)?$/) {
+ if ($line =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) (http[^ ]*) (\d+)(?:\\n.*)?$/) {
my ($leftx, $rightx, $topy, $bottomy, $url, $bugid) = ($1, $3, $2, $4, $5, $6);
# Pick up bugid from the mapdata label field. Getting the title from
# bugtitle hash instead of mapdata allows us to get the summary even
# when showsummary is off, and also gives us status and resolution.
+ # This text is safe; it has already been escaped.
my $bugtitle = $bugtitles{$bugid};
+
+ # The URL is supposed to be safe, because it's built manually.
+ # But in case someone manages to inject code, it's safer to escape it.
+ $url = html_quote($url);
+
$map .= qq{<area alt="bug $bugid" name="bug$bugid" shape="rect" } .
qq{title="$bugtitle" href="$url" } .
qq{coords="$leftx,$topy,$rightx,$bottomy">\n};
@@ -198,6 +204,9 @@ foreach my $k (@bug_ids) {
utf8::encode($summary) if utf8::is_utf8($summary);
}
$summary =~ s/([\\\"])/\\$1/g;
+ # Newlines must be escaped too, to not break the .map file
+ # and to prevent code injection.
+ $summary =~ s/\n/\\n/g;
push(@params, qq{label="$k\\n$summary"});
}
diff --git a/taskgraph.json b/taskgraph.json
index f292653be..7433db6f2 100644
--- a/taskgraph.json
+++ b/taskgraph.json
@@ -10,6 +10,7 @@
"reruns": 3,
"maxRunTime": 3000,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "Basic Sanity Tests"
},
@@ -25,13 +26,19 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "San"
+ "symbol": "San",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -40,6 +47,7 @@
"reruns": 3,
"maxRunTime": 3000,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "Documentation Build Test"
},
@@ -55,13 +63,19 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "Doc"
+ "symbol": "Doc",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -70,6 +84,7 @@
"reruns": 3,
"maxRunTime": 7200,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "WebService API Tests (MySQL)"
},
@@ -85,18 +100,24 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/httpd_error_log": {
"type": "file",
"path": "/var/log/httpd/error_log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "API"
+ "symbol": "API",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -105,6 +126,7 @@
"reruns": 3,
"maxRunTime": 7200,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "Selenium Tests (MySQL)"
},
@@ -120,23 +142,29 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/httpd_error_log": {
"type": "file",
"path": "/var/log/httpd/error_log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/selenium_log": {
"type": "file",
"path": "/selenium.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "Sel"
+ "symbol": "Sel",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -145,6 +173,7 @@
"reruns": 3,
"maxRunTime": 7200,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "WebService API Tests (Pg)"
},
@@ -160,18 +189,24 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/httpd_error_log": {
"type": "file",
"path": "/var/log/httpd/error_log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "API-Pg"
+ "symbol": "API-Pg",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -180,6 +215,7 @@
"reruns": 3,
"maxRunTime": 7200,
"task": {
+ "expires": "2018-02-18T17:33:38.806Z",
"metadata": {
"name": "Selenium Tests (Pg)"
},
@@ -195,23 +231,29 @@
"public/runtests_log": {
"type": "file",
"path": "/runtests.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/httpd_error_log": {
"type": "file",
"path": "/var/log/httpd/error_log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
},
"public/selenium_log": {
"type": "file",
"path": "/selenium.log",
- "expires": "2016-02-17T17:33:38.806Z"
+ "expires": "2018-02-17T17:33:38.806Z"
}
}
},
"extra": {
"treeherder": {
- "symbol": "Sel-Pg"
+ "symbol": "Sel-Pg",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl
index 65aa861a1..a1a074372 100644
--- a/template/en/default/account/auth/login-small.html.tmpl
+++ b/template/en/default/account/auth/login-small.html.tmpl
@@ -27,8 +27,6 @@
<a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]"
onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a>
- [% Hook.process('additional_methods') %]
-
<form action="[% login_target FILTER html %]" method="POST"
class="mini_login bz_default_hidden"
id="mini_login[% qs_suffix FILTER html %]">
@@ -56,24 +54,28 @@
<a href="#" onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a>
</form>
</li>
-<li id="forgot_container[% qs_suffix %]">
- <span class="separator">| </span>
- <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
- onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a>
- <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]"
- class="mini_forgot bz_default_hidden">
- <label for="login[% qs_suffix FILTER html %]">Login:</label>
- <input name="loginname" size="20" id="login[% qs_suffix FILTER html %]" required
- [% IF login_not_email %]
- placeholder="Your Login"
- [% ELSE %]
- type="email" placeholder="Your Email Address"
- [% END %]>
- <input id="forgot_button[% qs_suffix %]" value="Reset Password"
- type="submit">
- <input type="hidden" name="a" value="reqpw">
- <input type="hidden" id="token[% qs_suffix FILTER html %]" name="token"
- value="[% issue_hash_token(['reqpw']) FILTER html %]">
- <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a>
- </form>
-</li>
+
+[% Hook.process('additional_methods') %]
+
+[% IF user.authorizer.can_change_password %]
+ <li id="forgot_container[% qs_suffix %]">
+ <span class="separator">| </span>
+ <a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
+ onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a>
+ <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]"
+ class="mini_forgot bz_default_hidden">
+ <label for="login[% qs_suffix FILTER html %]">Login:</label>
+ <input name="loginname" size="20" id="login[% qs_suffix FILTER html %]" required
+ [% IF login_not_email %]
+ placeholder="Your Login"
+ [% ELSE %]
+ type="email" placeholder="Your Email Address"
+ [% END %]>
+ <input id="forgot_button[% qs_suffix %]" value="Reset Password" type="submit">
+ <input type="hidden" name="a" value="reqpw">
+ <input type="hidden" id="token[% qs_suffix FILTER html %]" name="token"
+ value="[% issue_hash_token(['reqpw']) FILTER html %]">
+ <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a>
+ </form>
+ </li>
+[% END %]
diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl
index 6c0e0cb78..7505ebd8c 100644
--- a/template/en/default/admin/flag-type/edit.html.tmpl
+++ b/template/en/default/admin/flag-type/edit.html.tmpl
@@ -23,7 +23,7 @@
title = title
style_urls = ['skins/standard/admin.css']
onload="var f = document.forms['flagtype_properties'];
- selectProduct(f.product, f.component, null, null, '__Any__');"
+ selectProduct(f.product, f.component, '__Any__');"
javascript_urls=["js/productform.js"]
doc_section = "administering/flags.html"
%]
@@ -92,7 +92,7 @@
id => "product"
name => "product"
add => "__Any__"
- onchange => "selectProduct(this, this.form.component, null, null, '__Any__');"
+ onchange => "selectProduct(this, this.form.component, '__Any__');"
products => products
%]<br>
<select name="component">
diff --git a/template/en/default/admin/flag-type/list.html.tmpl b/template/en/default/admin/flag-type/list.html.tmpl
index b91b49199..b1665c3b0 100644
--- a/template/en/default/admin/flag-type/list.html.tmpl
+++ b/template/en/default/admin/flag-type/list.html.tmpl
@@ -11,7 +11,7 @@
[% PROCESS global/header.html.tmpl
title = 'Administer Flag Types'
style_urls = ['skins/standard/admin.css']
- onload="var f = document.flagtype_form; selectProduct(f.product, f.component, null, null, '__All__');"
+ onload="var f = document.flagtype_form; selectProduct(f.product, f.component, '__All__');"
javascript_urls=["js/productform.js"]
doc_section = "administering/flags.html"
%]
@@ -43,7 +43,7 @@
id => "product"
name => "product"
add => "__Any__"
- onchange => "selectProduct(this, this.form.component, null, null, '__Any__');"
+ onchange => "selectProduct(this, this.form.component, '__Any__');"
products => products
%]
</div>
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index d73d75e13..830a7e7f6 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -49,7 +49,7 @@
the error [% bug.error FILTER html %].
[% ELSIF error == "chart_data_not_generated" %]
- [% admindocslinks = {'extraconfig.html' => 'Setting up Charting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Setting up Charting'} %]
[% IF product.id %]
Charts for the <em>[% product.name FILTER html %]</em> product are not
available yet because no charting data has been collected for it since it
@@ -290,6 +290,14 @@
a <code>[% param FILTER html %]</code> argument, and that
argument was not set.
+ [% ELSIF error == "param_integer_required" %]
+ The function <code>[% function FILTER html %]</code> requires
+ that <code>[% param FILTER html %]</code> be an integer.
+
+ [% ELSIF error == "param_scalar_array_required" %]
+ The <code>[% param FILTER html %]</code> parameter must be an array of scalars
+ (integers and/or strings).
+
[% ELSIF error == "params_required" %]
[% title = "Missing Parameter" %]
The function <code>[% function FILTER html %]</code> requires
diff --git a/template/en/default/global/docslinks.html.tmpl b/template/en/default/global/docslinks.html.tmpl
index e33aa3b17..94502aa1f 100644
--- a/template/en/default/global/docslinks.html.tmpl
+++ b/template/en/default/global/docslinks.html.tmpl
@@ -7,29 +7,29 @@
#%]
[%# INTERFACE:
- # docslinks: hash. Hash keys will be used as text of the documentation links,
- # hash values will be used as links to the document, relative to
+ # docslinks: hash. Hash values will be used as text of the documentation links,
+ # hash keys will be used as links to the document, relative to
# the main Bugzilla documentation directory.
# Example: If you want a 'FAQ' link to point to, the "faq-general"
# named anchor on faq.html, assign
- # { 'FAQ' => "faq.html#faq-general" }
+ # { "faq.html#faq-general" => 'FAQ' }
# to docslinks.
# You may only link to sections by their given ID; it is not allowed
# to link to a section which is not given an ID (thus getting
# assigned an automatically generated ID). Otherwise, the link
# would break on a recompilation of the documentation.
# admindocslinks: hash. Same as docslinks, but will only be displayed to
- # members of the admin group.
+ # members of the 'editcomponents' group.
#%]
-[% IF docslinks.keys.size || (admindocslinks.keys.size && user.in_group('admin')) %]
+[% IF docslinks.keys.size || (admindocslinks.keys.size && user.in_group('editcomponents')) %]
<div id="docslinks">
<h2>Related documentation</h2>
<ul>
- [% IF user.in_group('admin') %]
- [% PROCESS docslinkslist docstype = admindocslinks %]
+ [% IF user.in_group('editcomponents') %]
+ [% PROCESS docslinkslist docstype = admindocslinks admin = 1 %]
[% END %]
- [% PROCESS docslinkslist docstype = docslinks %]
+ [% PROCESS docslinkslist docstype = docslinks admin = 0 %]
</ul>
</div>
[% END %]
@@ -37,7 +37,7 @@
[% BLOCK docslinkslist %]
[% FOREACH docslink = docstype.keys %]
<li>
- <a href="[% docs_urlbase FILTER html %]
+ <a href="[% docs_urlbase FILTER html %][% "administering/" IF admin %]
[% docslink FILTER none %]">[% docstype.$docslink FILTER html %]</a>
</li>
[% END %]
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index 3b8dc3a3b..287209582 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -35,6 +35,7 @@
javascript_urls = []
yui = []
generate_api_token = 0
+ favicon_url = "images/favicon.ico"
%]
[% SET yui_css = {
@@ -208,7 +209,7 @@
[%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %]
<link rel="search" type="application/opensearchdescription+xml"
title="[% terms.Bugzilla %]" href="./search_plugin.cgi">
- <link rel="shortcut icon" href="images/favicon.ico" >
+ <link rel="shortcut icon" href="[% favicon_url FILTER html %]">
[% Hook.process("additional_header") %]
</head>
diff --git a/template/en/default/global/js-products.html.tmpl b/template/en/default/global/js-products.html.tmpl
index e40a3e3ae..940a5e64d 100644
--- a/template/en/default/global/js-products.html.tmpl
+++ b/template/en/default/global/js-products.html.tmpl
@@ -8,14 +8,13 @@
[%# The javascript block gets used in header.html.tmpl. %]
[% javascript = BLOCK %]
- var useclassification = false; // No classification level in use
var first_load = true; // Is this the first time we load the page?
var last_sel = []; // Caches last selection
var cpts = new Array();
+
[% n = 1 %]
[% FOREACH prod = products %]
- cpts['[% n %]'] = [
- [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
+ cpts['[% n %]'] = [[% FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%]];
[% n = n+1 %]
[% END %]
[% END %]
diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl
index 3a8aa1ada..bc8fe5b38 100644
--- a/template/en/default/global/messages.html.tmpl
+++ b/template/en/default/global/messages.html.tmpl
@@ -879,9 +879,16 @@
[% title = "$terms.Bugzilla is Down" %]
[% Param("shutdownhtml") %]
[% IF userid %]
- <p>For security reasons, you have been logged out automatically.
- The cookie that was remembering your login is now gone.
+ <p>
+ For security reasons, you have been logged out automatically.
+ The cookie that was remembering your login is now gone.
+ </p>
[% END %]
+ <p>
+ If you are an administrator, you can
+ <a href="editparams.cgi?section=general">reactivate [% terms.Bugzilla %]</a>
+ by clearing the <kbd>shutdownhtml</kbd> parameter.
+ </p>
[% ELSIF message_tag == "term" %]
[% terms.$term FILTER html %]
diff --git a/template/en/default/global/tabs.html.tmpl b/template/en/default/global/tabs.html.tmpl
index 9cf5a897b..511640477 100644
--- a/template/en/default/global/tabs.html.tmpl
+++ b/template/en/default/global/tabs.html.tmpl
@@ -25,7 +25,7 @@
[% tab.label FILTER html %]</td>
[% ELSE %]
<td id="tab_[% tab.name FILTER html %]" class="clickable_area"
- onClick="document.location='[% tab.link FILTER html %]'">
+ onClick="document.location='[% tab.link FILTER js FILTER html %]'">
<a href="[% tab.link FILTER html %]">[% tab.label FILTER html %]</a>
</td>
[% END %]
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index b5d2daf70..cc1ad1994 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -119,7 +119,7 @@
[% ELSIF error == "auth_failure" %]
[% title = "Authorization Required" %]
- [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ [% admindocslinks = {'groups.html#groups' => 'Group Security'} %]
Sorry,
[% IF group %]
you aren't a member of the '[% group FILTER html %]' group,
@@ -257,12 +257,12 @@
[% ELSIF error == "bug_access_denied" %]
[% title = "$terms.Bug Access Denied" %]
- [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ [% admindocslinks = {'groups.html#groups' => 'Group Security'} %]
You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %].
[% ELSIF error == "bug_access_query" %]
[% title = "$terms.Bug Access Denied" %]
- [% docslinks = {'myaccount.html' => 'Creating an account'} %]
+ [% docslinks = {'administering/users.html#creating-new-users' => 'Creating an account'} %]
You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %].
To see this [% terms.bug %], you must
first <a href="show_bug.cgi?id=
@@ -304,8 +304,8 @@
[% ELSIF error == "buglist_parameters_required" %]
[% title = "Parameters Required" %]
- [% docslinks = {'query.html' => "Searching for $terms.bugs",
- 'query.html#list' => "$terms.Bug lists"} %]
+ [% docslinks = {'using/finding.html' => "Searching for $terms.bugs",
+ 'using/finding.html#bug-lists' => "$terms.Bug lists"} %]
You may not search, or create saved searches, without any search terms.
[% ELSIF error == "cc_remove_denied" %]
@@ -518,7 +518,7 @@
[% ELSIF error == "entry_access_denied" %]
[% title = "Permission Denied" %]
- [% admindocslinks = {'groups.html' => 'Group Security'} %]
+ [% admindocslinks = {'categorization.html#product-group-controls' => 'Group Security'} %]
Sorry, either the product <em>[% product FILTER html %]</em>
does not exist or you aren't authorized to
enter [% terms.abug %] into it.
@@ -717,10 +717,9 @@
[% ELSIF error == "flag_requestee_unauthorized" %]
[% title = "Flag Requestee Not Authorized" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
- 'groups.html' => 'Group Security'} %]
- [% docslinks = {'flags-overview.html' => 'An overview on Flags',
- 'flags.html' => 'Using Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags',
+ 'categorization.html#assigning-group-controls-to-products' => 'Group Security'} %]
+ [% docslinks = {'using/understanding.html#flags' => 'Using Flags'} %]
You asked [% requestee.identity FILTER html %]
for <code>[% flag_type.name FILTER html %]</code> on [% terms.bug %]
@@ -734,10 +733,9 @@
[% ELSIF error == "flag_requestee_unauthorized_attachment" %]
[% title = "Flag Requestee Not Authorized" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
- 'groups.html' => 'Group Security'} %]
- [% docslinks = {'flags-overview.html' => 'An overview on Flags',
- 'flags.html' => 'Using Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags',
+ 'categorization.html#assigning-group-controls-to-products' => 'Group Security'} %]
+ [% docslinks = {'using/understanding.html#flags' => 'Using Flags'} %]
You asked [% requestee.identity FILTER html %]
for <code>[% flag_type.name FILTER html %]</code> on
@@ -767,7 +765,7 @@
[% ELSIF error == "flag_type_cc_list_invalid" %]
[% title = "Flag Type CC List Invalid" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags'} %]
The CC list [% cc_list FILTER html %] must be less than 200 characters long.
[% ELSIF error == "flag_type_component_without_product" %]
@@ -776,12 +774,12 @@
[% ELSIF error == "flag_type_description_invalid" %]
[% title = "Flag Type Description Invalid" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags'} %]
You must enter a description for this flag type.
[% ELSIF error == "flag_type_name_invalid" %]
[% title = "Flag Type Name Invalid" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags'} %]
The name <em>[% name FILTER html %]</em> must be 1-50 characters long
and must not contain any spaces or commas.
@@ -801,17 +799,15 @@
You must specify the type id value to update or add a flag.
[% ELSIF error == "flag_type_not_multiplicable" %]
- [% docslinks = {'flags-overview.html' => 'An overview on Flags',
- 'flags.html' => 'Using Flags'} %]
+ [% docslinks = {'using/understanding.html#flags' => 'Using Flags'} %]
You cannot have several <em>[% type.name FILTER html %]</em> flags
for this [% IF attachment %] attachment [% ELSE %] [%+ terms.bug %] [% END %].
[% ELSIF error == "flag_update_denied" %]
[% title = "Flag Modification Denied" %]
- [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags',
- 'groups.html' => 'Group Security'} %]
- [% docslinks = {'flags-overview.html' => 'An overview on Flags',
- 'flags.html' => 'Using Flags'} %]
+ [% admindocslinks = {'flags.html' => 'Administering Flags',
+ 'categorization.html#assigning-group-controls-to-products' => 'Group Security'} %]
+ [% docslinks = {'using/understanding.html#flags' => 'Using Flags'} %]
You tried to [% IF status == "+" %] grant [% ELSIF status == "-" %] deny
[% ELSIF status == "X" %] clear [% ELSE %] request [% END %]
<code>[% name FILTER html %]
@@ -969,7 +965,7 @@
[% ELSIF error == "illegal_group_control_combination" %]
[% title = "Your Group Control Combination Is Illegal" %]
- [% admindocslinks = {'groups.html' => 'Assigning Group Controls to Products'} %]
+ [% admindocslinks = {'categorization.html#assigning-group-controls-to-products' => 'Assigning Group Controls to Products'} %]
Your group control combination for group &quot;
[% groupname FILTER html %]&quot; is illegal.
@@ -986,13 +982,13 @@
&lt;, &gt;, &amp;.
[% ELSIF error == "illegal_series_creation" %]
- [% admindocslinks = {'groups.html' => 'Group security'} %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% admindocslinks = {'categorization.html#assigning-group-controls-to-products' => 'Group security'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You are not authorized to create series.
[% ELSIF error == "illegal_series_edit" %]
- [% admindocslinks = {'groups.html' => 'Group security'} %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% admindocslinks = {'categorization.html#assigning-group-controls-to-products' => 'Group security'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You are not authorized to edit this series. To do this, you must either
be its creator, or an administrator.
@@ -1009,7 +1005,7 @@
The error was: [% dberror FILTER html %].
[% ELSIF error == "insufficient_data_points" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
We don't have enough data points to make a graph (yet).
[% ELSIF error == "invalid_attach_id" %]
@@ -1214,8 +1210,8 @@
[% ELSIF error == "milestone_already_exists" %]
[% title = "Milestone Already Exists" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'milestones.html' => 'About Milestones'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#milestones' => 'About Milestones'} %]
The milestone '[% name FILTER html %]' already exists for product '
[%- product FILTER html %]'.
@@ -1225,8 +1221,8 @@
[% ELSIF error == "milestone_is_default" %]
[% title = "Default milestone not deletable" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'milestones.html' => 'About Milestones'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#milestones' => 'About Milestones'} %]
Sorry, but [% milestone.name FILTER html %] is the default milestone
for the '[% milestone.product.name FILTER html %]' product, and so
it cannot be deleted.
@@ -1273,8 +1269,8 @@
[% ELSIF error == "missing_component" %]
[% title = "Missing Component" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'components.html' => 'Creating a component'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#milestones' => 'Creating a component'} %]
Sorry, the product <em>[% product.name FILTER html %]</em>
has to have at least one active component in order for you to
enter [% terms.abug %] into it.<br>
@@ -1297,26 +1293,26 @@
Sorry, I seem to have lost the cookie that recorded
the results of your last search. I'm afraid you will have to start
again from the <a href="query.cgi">search page</a>.
-
+
[% ELSIF error == "missing_datasets" %]
[% title = "No Datasets Selected" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You must specify one or more datasets to plot.
-
+
[% ELSIF error == "missing_frequency" %]
[% title = "Missing Frequency" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You did not specify a valid frequency for this series.
-
+
[% ELSIF error == "missing_name" %]
[% title = "Missing Name" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You did not specify a name for this series.
-
+
[% ELSIF error == "missing_query" %]
[% title = "Missing Search" %]
- [% docslinks = {'query.html' => "Searching for $terms.bugs",
- 'query.html#list' => "$terms.Bug lists"} %]
+ [% docslinks = {'using/finding.html' => "Searching for $terms.bugs",
+ 'using/finding.html#bug-lists' => "$terms.Bug lists"} %]
The search named <em>[% name FILTER html %]</em>
[% IF sharer_id && sharer_id != user.id %]
has not been made visible to you.
@@ -1339,7 +1335,7 @@
[% ELSIF error == "missing_version" %]
[% title = "Missing Version" %]
- [% admindocslinks = {'versions.html' => 'Defining versions'} %]
+ [% admindocslinks = {'categorization.html#versions' => 'Defining versions'} %]
Sorry, the product <em>[% product.name FILTER html %]</em>
has to have at least one active version in order for you to
enter [% terms.abug %] into it.<br>
@@ -1357,7 +1353,7 @@
[% ELSIF error == "need_quip" %]
[% title = "Quip Required" %]
- [% docslinks = {'quips.html' => 'About quips'} %]
+ [% docslinks = {'administering/quips.html' => 'About quips'} %]
Please enter a quip in the text field.
[% ELSIF error == "new_password_missing" %]
@@ -1366,7 +1362,7 @@
[% ELSIF error == "no_axes_defined" %]
[% title = "No Axes Defined" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
You didn't define any axes to plot.
[% ELSIF error == "no_bugs_chosen" %]
@@ -1405,9 +1401,11 @@
[% ELSIF error == "no_products" %]
[% title = "No Products" %]
- [% admindocslinks = {'products.html' => 'Setting up a product',
- 'components.html' => 'Adding components to products',
- 'groups.html' => 'Groups security'} %]
+ [% admindocslinks = {
+ 'categorization.html#creating-new-products' => 'Setting up a product',
+ 'categorization.html#components' => 'Adding components to products',
+ 'categorization.html#product-group-controls' => 'Groups security'
+ } %]
Either no products have been defined to enter [% terms.bugs %] against or you have not
been given access to any.
@@ -1523,12 +1521,12 @@
[% ELSIF error == "product_name_already_in_use" %]
[% title = "Product name already exists" %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
The product name '[% product FILTER html %]' already exists.
[% ELSIF error == "product_name_diff_in_case" %]
[% title = "Product name differs only in case" %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
The product name '[% product FILTER html %]' differs from existing
product '[% existing_product FILTER html %]' only in case.
@@ -1539,8 +1537,8 @@
[% ELSIF error == "product_must_define_defaultmilestone" %]
[% title = "Must define new default milestone" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'milestones.html' => 'About Milestones'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#milestones' => 'About Milestones'} %]
You must <a href="editmilestones.cgi?action=add&amp;product=[% product FILTER uri %]">
create the milestone '[% milestone FILTER html %]'</a> before
it can be made the default milestone for product '[% product FILTER html %]'.
@@ -1551,38 +1549,38 @@
[% ELSIF error == "product_blank_name" %]
[% title = "Blank Product Name Not Allowed" %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
You must enter a name for the product.
[% ELSIF error == "product_disabled" %]
[% title = BLOCK %]Product closed for [% terms.Bug %] Entry[% END %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
Sorry, entering [% terms.abug %] into the
product <em>[% product.name FILTER html %]</em> has been disabled.
[% ELSIF error == "product_edit_denied" %]
[% title = "Product Edit Access Denied" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'groups.html' => 'Group security'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#assigning-group-controls-to-products' => 'Group security'} %]
You are not permitted to edit [% terms.bugs %] in product
[%+ product FILTER html %].
[% ELSIF error == "product_has_bugs" %]
[% title = BLOCK %]Product has [% terms.Bugs %][% END %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
There are [% nb FILTER html %] [%+ terms.bugs %] entered for this product!
You must move those [% terms.bugs %] to another product before you
can delete this one.
[% ELSIF error == "product_must_have_description" %]
[% title = "Product needs Description" %]
- [% admindocslinks = {'products.html' => 'Administering products'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products'} %]
You must enter a description for this product.
[% ELSIF error == "product_must_have_version" %]
[% title = "Product needs Version" %]
- [% admindocslinks = {'products.html' => 'Administering products',
- 'versions.html' => 'Administering versions'} %]
+ [% admindocslinks = {'categorization.html#products' => 'Administering products',
+ 'categorization.html#versions' => 'Administering versions'} %]
You must enter a valid version to create a new product.
[% ELSIF error == "product_unknown_component" %]
@@ -1596,7 +1594,7 @@
[% ELSIF error == "query_name_missing" %]
[% title = "No Search Name Specified" %]
- [% docslinks = {'query.html#list' => "$terms.Bug lists"} %]
+ [% docslinks = {'using/finding.html#bug-lists' => "$terms.Bug lists"} %]
You must enter a name for your search.
[% ELSIF error == "query_name_too_long" %]
@@ -1705,7 +1703,7 @@
[% ELSIF error == "saved_search_used_by_whines" %]
[% title = "Saved Search In Use" %]
- [% docslinks = {'whining.html' => 'About Whining'} %]
+ [% docslinks = {'administering/whining.html' => 'About Whining'} %]
The saved search <em>[% search_name FILTER html %]</em> is being used
by <a href="editwhines.cgi">Whining events</a> with the following subjects:
[%+ subjects FILTER html %]
@@ -1739,7 +1737,7 @@
[% ELSIF error == "series_already_exists" %]
[% title = "Series Already Exists" %]
- [% docslinks = {'reporting.html' => 'Reporting'} %]
+ [% docslinks = {'using/reports-and-charts.html' => 'Reporting'} %]
A series named <em>[% series.category FILTER html %] /
[%+ series.subcategory FILTER html %] /
[%+ series.name FILTER html %]</em>
@@ -1842,7 +1840,7 @@
[% ELSIF error == "version_already_exists" %]
[% title = "Version Already Exists" %]
- [% admindocslinks = {'versions.html' => 'Administering versions'} %]
+ [% admindocslinks = {'categorization.html#versions' => 'Administering versions'} %]
The version '[% name FILTER html %]' already exists for product '
[%- product FILTER html %]'.
@@ -1863,12 +1861,12 @@
[% ELSIF error == "users_deletion_disabled" %]
[% title = "Deletion not activated" %]
- [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ [% admindocslinks = {'users.html#deleting-users' => 'User administration'} %]
Sorry, the deletion of user accounts is not allowed.
[% ELSIF error == "user_has_responsibility" %]
[% title = "Can't Delete User Account" %]
- [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ [% admindocslinks = {'users.html#deleting-users' => 'User administration'} %]
The user you want to delete is set up as the default [% terms.bug %]
assignee
[% IF Param('useqacontact') %]
@@ -1889,7 +1887,7 @@
[% ELSIF error == "user_login_required" %]
[% title = "Login Name Required" %]
- [% admindocslinks = {'useradmin.html' => 'User administration'} %]
+ [% admindocslinks = {'users.html' => 'User administration'} %]
You must enter a login name for the new user.
[% ELSIF error == "user_match_failed" %]
diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl
index 5bd1608d9..358298bc8 100644
--- a/template/en/default/pages/release-notes.html.tmpl
+++ b/template/en/default/pages/release-notes.html.tmpl
@@ -43,6 +43,40 @@
<h2 id="point">Updates in this 5.0.x Release</h2>
+<h3>5.0.3</h3>
+
+<p>This release fixes one security issue. See the
+ <a href="https://www.bugzilla.org/security/4.4.11/">Security Advisory</a>
+ for details.</p>
+
+<p>This release also contains the following [% terms.bug %] fixes:</p>
+
+<ul>
+ <li>A regression in Bugzilla 5.0.2 caused <kbd>whine.pl</kbd> to be unable
+ to send emails due to a missing subroutine.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1235395">[% terms.Bug %] 1235395</a>)</li>
+ <li>The <kbd>Encode</kbd> module changed the way it encodes strings, causing
+ email addresses in emails sent by [%terms.Bugzilla %] to be encoded,
+ preventing emails from being correctly delivered to recipients.
+ We now encode email headers correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1246228">[% terms.Bug %] 1246228</a>)</li>
+ <li>Fix additional taint issues with Strawberry Perl.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=987742">[% terms.Bug %] 987742</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1089448">[% terms.bug %] 1089448</a>)</li>
+ <li>When exporting a buglist as a CSV file, fields starting with either
+ "=", "+", "-" or "@" are preceded by a space to not trigger formula
+ execution in Excel.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1259881">[% terms.Bug %] 1259881</a>)</li>
+ <li>An extension which allows user-controlled data to be used as a link in
+ tabs could trigger XSS if the data is not correctly sanitized.
+ [%+ terms. Bugzilla %] no longer relies on the extension to do the sanity
+ check. A vanilla installation is not affected as no tab is user-controlled.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1250114">[% terms.Bug %] 1250114</a>)</li>
+ <li>Extensions can now easily override the favicon used for the
+ [%+ terms.Bugzilla %] website.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1250264">[% terms.Bug %] 1250264</a>)</li>
+</ul>
+
<h3>5.0.2</h3>
<p>This release fixes two security issues. See the
diff --git a/template/en/default/request/queue.html.tmpl b/template/en/default/request/queue.html.tmpl
index 7e8c44c8b..101fdd046 100644
--- a/template/en/default/request/queue.html.tmpl
+++ b/template/en/default/request/queue.html.tmpl
@@ -9,40 +9,17 @@
[% USE Bugzilla %]
[% cgi = Bugzilla.cgi %]
+[% PROCESS "global/js-products.html.tmpl" %]
+
[% PROCESS global/header.html.tmpl
title="Request Queue"
generate_api_token = 1
- onload="var f = document.request_form; selectProduct(f.product, f.component, null, null, 'Any');"
+ onload="var f = document.request_form; selectProduct(f.product, f.component, 'Any');"
javascript_urls=["js/productform.js", "js/field.js"]
style_urls = ['skins/standard/buglist.css']
yui = ['autocomplete']
%]
-<script type="text/javascript">
- var useclassification = false; // No classification level in use
- var first_load = true; // Is this the first time we load the page?
- var last_sel = []; // Caches last selection
- var cpts = new Array();
- [% n = 1 %]
- [% IF Param('useclassification') %]
- [% FOREACH clas = user.get_selectable_classifications %]
- [% FOREACH prod = user.get_selectable_products(clas.id) %]
- [%+ PROCESS js_comp %]
- [% END %]
- [% END %]
- [% ELSE %]
- [% FOREACH prod = user.get_selectable_products %]
- [%+ PROCESS js_comp %]
- [% END %]
- [% END %]
-</script>
-
-[% BLOCK js_comp %]
- cpts['[% n %]'] = [
- [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%]];
- [% n = n+1 %]
-[% END %]
-
<p>
When you are logged in, only requests made by you or addressed to you
are shown by default. You can change the criteria using the form below.
@@ -72,7 +49,7 @@ to some group are shown by default.
id => "product"
name => "product"
add => "Any"
- onchange => "selectProduct(this, this.form.component, null, null, 'Any');"
+ onchange => "selectProduct(this, this.form.component, 'Any');"
%]
</td>
<th>Flag:</th>
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index 0420811ee..ac8aeaf61 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -247,7 +247,7 @@ TUI_hide_default('information_query');
[% FOREACH qv = [
{ name => "substring", description => "contains" },
{ name => "notsubstring", description => "doesn't contain" },
- { name => "exact", description => "is" },
+ { name => "equals", description => "is" },
{ name => "notequals", description => "is not" },
{ name => "regexp", description => "matches regexp" },
{ name => "notregexp", description => "doesn't match regexp" } ] %]