aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla.pm1
-rw-r--r--Bugzilla/Bug.pm14
-rw-r--r--Bugzilla/BugMail.pm4
-rw-r--r--Bugzilla/CGI.pm5
-rw-r--r--Bugzilla/Component.pm5
-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
-rw-r--r--docs/en/Makefile2
-rw-r--r--docs/en/rst/api/index.rst3
-rw-r--r--docs/en/rst/conf.py11
-rw-r--r--docs/en/rst/installing/iis.rst3
-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/windows.rst2
-rw-r--r--docs/en/rst/integrating/apis.rst13
-rwxr-xr-xdocs/makedocs.pl10
-rwxr-xr-xeditclassifications.cgi2
-rwxr-xr-xeditgroups.cgi18
-rwxr-xr-xeditkeywords.cgi18
-rwxr-xr-xprocess_bug.cgi7
-rwxr-xr-xshowdependencygraph.cgi3
-rw-r--r--taskgraph.json48
-rw-r--r--template/en/default/global/code-error.html.tmpl8
-rw-r--r--template/en/default/global/tabs.html.tmpl2
-rw-r--r--template/en/default/pages/release-notes.html.tmpl34
-rw-r--r--template/en/default/search/form.html.tmpl2
34 files changed, 223 insertions, 133 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 9cb15a7ee..e4772e08b 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -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/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/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/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 ce027171b..41b9265c6 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;
@@ -865,12 +865,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 5db8f5909..40b0c9d3a 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/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/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/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/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/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/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/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/showdependencygraph.cgi b/showdependencygraph.cgi
index 476df1e8e..6d4cb1e71 100755
--- a/showdependencygraph.cgi
+++ b/showdependencygraph.cgi
@@ -198,6 +198,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 24476c83d..7433db6f2 100644
--- a/taskgraph.json
+++ b/taskgraph.json
@@ -32,7 +32,13 @@
},
"extra": {
"treeherder": {
- "symbol": "San"
+ "symbol": "San",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -63,7 +69,13 @@
},
"extra": {
"treeherder": {
- "symbol": "Doc"
+ "symbol": "Doc",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -99,7 +111,13 @@
},
"extra": {
"treeherder": {
- "symbol": "API"
+ "symbol": "API",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -140,7 +158,13 @@
},
"extra": {
"treeherder": {
- "symbol": "Sel"
+ "symbol": "Sel",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -176,7 +200,13 @@
},
"extra": {
"treeherder": {
- "symbol": "API-Pg"
+ "symbol": "API-Pg",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
@@ -217,7 +247,13 @@
},
"extra": {
"treeherder": {
- "symbol": "Sel-Pg"
+ "symbol": "Sel-Pg",
+ "machine": {
+ "platform": "linux64"
+ },
+ "build": {
+ "platform": "linux64"
+ }
}
}
}
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index 63f3ae9d9..830a7e7f6 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -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/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/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/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" } ] %]