aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2015-02-07 10:46:12 -0800
committerRobin H. Johnson <robbat2@gentoo.org>2015-02-07 10:46:12 -0800
commit6f8a072654b599c6a316898fedb917445ec46f5e (patch)
tree4f4fc6b9411b766ffada0a9c02ab510b5dc8969b
parentMerge tag 'bugzilla-4.4.6' into upstream (diff)
parentBumped version to 4.4.7 (diff)
downloadbugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.tar.gz
bugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.tar.bz2
bugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.zip
Merge tag 'release-4.4.7' into upstream
-rw-r--r--Bugzilla/Attachment.pm4
-rw-r--r--Bugzilla/Attachment/PatchReader.pm2
-rw-r--r--Bugzilla/Bug.pm12
-rw-r--r--Bugzilla/CGI.pm1
-rw-r--r--Bugzilla/Config/Common.pm17
-rw-r--r--Bugzilla/Config/MTA.pm3
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/DB.pm9
-rw-r--r--Bugzilla/Error.pm2
-rw-r--r--Bugzilla/FlagType.pm19
-rw-r--r--Bugzilla/Install/CPAN.pm4
-rw-r--r--Bugzilla/Install/Filesystem.pm2
-rw-r--r--Bugzilla/Search.pm37
-rw-r--r--Bugzilla/Send/Sendmail.pm2
-rw-r--r--Bugzilla/UserAgent.pm1
-rw-r--r--Bugzilla/WebService.pm4
-rw-r--r--Bugzilla/WebService/Bug.pm33
-rw-r--r--Bugzilla/WebService/Bugzilla.pm9
-rw-r--r--Bugzilla/WebService/Classification.pm4
-rw-r--r--Bugzilla/WebService/Group.pm5
-rw-r--r--Bugzilla/WebService/Product.pm9
-rw-r--r--Bugzilla/WebService/Server/JSONRPC.pm6
-rw-r--r--Bugzilla/WebService/Server/XMLRPC.pm11
-rw-r--r--Bugzilla/WebService/User.pm43
-rw-r--r--Bugzilla/WebService/Util.pm6
-rwxr-xr-xattachment.cgi13
-rwxr-xr-xcollectstats.pl2
-rw-r--r--docs/bugzilla.ent.tmpl6
-rw-r--r--docs/en/xml/using.xml5
-rw-r--r--extensions/Example/lib/WebService.pm5
-rwxr-xr-xreports.cgi2
-rwxr-xr-xsearch_plugin.cgi2
-rwxr-xr-xshowdependencygraph.cgi6
-rw-r--r--template/en/default/bug/dependency-tree.html.tmpl7
-rw-r--r--template/en/default/global/code-error.html.tmpl6
-rw-r--r--template/en/default/global/user-error.html.tmpl5
-rw-r--r--template/en/default/pages/release-notes.html.tmpl21
-rwxr-xr-xtestserver.pl6
38 files changed, 238 insertions, 95 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index 97cd85008..cd8316a91 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -342,7 +342,7 @@ sub data {
# If there's no attachment data in the database, the attachment is stored
# in a local file, so retrieve it from there.
if (length($self->{data}) == 0) {
- if (open(AH, $self->_get_local_filename())) {
+ if (open(AH, '<', $self->_get_local_filename())) {
local $/;
binmode AH;
$self->{data} = <AH>;
@@ -388,7 +388,7 @@ sub datasize {
# is stored in a local file, and so retrieve its size from the file,
# or the attachment has been deleted.
unless ($self->{datasize}) {
- if (open(AH, $self->_get_local_filename())) {
+ if (open(AH, '<', $self->_get_local_filename())) {
binmode AH;
$self->{datasize} = (stat(AH))[7];
close(AH);
diff --git a/Bugzilla/Attachment/PatchReader.pm b/Bugzilla/Attachment/PatchReader.pm
index 4026ba739..e75a660f2 100644
--- a/Bugzilla/Attachment/PatchReader.pm
+++ b/Bugzilla/Attachment/PatchReader.pm
@@ -99,7 +99,7 @@ sub process_interdiff {
# Send through interdiff, send output directly to template.
# Must hack path so that interdiff will work.
$ENV{'PATH'} = $lc->{diffpath};
- open my $interdiff_fh, "$lc->{interdiffbin} $old_filename $new_filename|";
+ open my $interdiff_fh, '-|', "$lc->{interdiffbin} $old_filename $new_filename";
binmode $interdiff_fh;
my ($reader, $last_reader) = setup_patch_readers("", $context);
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index d0e8f462b..b390c12d4 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -354,14 +354,16 @@ sub new {
sub check {
my $class = shift;
- my ($id, $field) = @_;
-
- ThrowUserError('improper_bug_id_field_value', { field => $field }) unless defined $id;
+ my ($param, $field) = @_;
# Bugzilla::Bug throws lots of special errors, so we don't call
# SUPER::check, we just call our new and do our own checks.
- $id = trim($id);
- my $self = $class->new($id);
+ my $id = ref($param)
+ ? ($param->{id} = trim($param->{id}))
+ : ($param = trim($param));
+ ThrowUserError('improper_bug_id_field_value', { field => $field }) unless defined $id;
+
+ my $self = $class->new($param);
if ($self->{error}) {
# For error messages, use the id that was returned by new(), because
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 7bb9d96c4..7df916b0c 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -344,6 +344,7 @@ sub header {
sub param {
my $self = shift;
+ local $CGI::LIST_CONTEXT_WARN = 0;
# When we are just requesting the value of a parameter...
if (scalar(@_) == 1) {
diff --git a/Bugzilla/Config/Common.pm b/Bugzilla/Config/Common.pm
index 0e3551d13..e1c2c8c40 100644
--- a/Bugzilla/Config/Common.pm
+++ b/Bugzilla/Config/Common.pm
@@ -23,7 +23,7 @@ use base qw(Exporter);
qw(check_multi check_numeric check_regexp check_url check_group
check_sslbase check_priority check_severity check_platform
check_opsys check_shadowdb check_urlbase check_webdotbase
- check_user_verify_class check_ip
+ check_user_verify_class check_ip check_smtp_server
check_mail_delivery_method check_notification check_utf8
check_bug_status check_smtp_auth check_theschwartz_available
check_maxattachmentsize check_email check_smtp_ssl
@@ -231,7 +231,7 @@ sub check_webdotbase {
# Check .htaccess allows access to generated images
my $webdotdir = bz_locations()->{'webdotdir'};
if(-e "$webdotdir/.htaccess") {
- open HTACCESS, "$webdotdir/.htaccess";
+ open HTACCESS, "<", "$webdotdir/.htaccess";
if(! grep(/ \\\.png\$/,<HTACCESS>)) {
return "Dependency graph images are not accessible.\nAssuming that you have not modified the file, delete $webdotdir/.htaccess and re-run checksetup.pl to rectify.\n";
}
@@ -325,6 +325,19 @@ sub check_notification {
return "";
}
+sub check_smtp_server {
+ my $host = shift;
+ my $port;
+
+ if ($host =~ /:/) {
+ ($host, $port) = split(/:/, $host, 2);
+ unless ($port && detaint_natural($port)) {
+ return "Invalid port. It must be an integer (typically 25, 465 or 587)";
+ }
+ }
+ return "";
+}
+
sub check_smtp_auth {
my $username = shift;
if ($username and !Bugzilla->feature('smtp_auth')) {
diff --git a/Bugzilla/Config/MTA.pm b/Bugzilla/Config/MTA.pm
index 8184b9f5e..e6e9505a3 100644
--- a/Bugzilla/Config/MTA.pm
+++ b/Bugzilla/Config/MTA.pm
@@ -49,7 +49,8 @@ sub get_param_list {
{
name => 'smtpserver',
type => 't',
- default => 'localhost'
+ default => 'localhost',
+ checker => \&check_smtp_server
},
{
name => 'smtp_username',
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 4f2cf6312..bd5b2dabc 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -182,7 +182,7 @@ use Memoize;
# CONSTANTS
#
# Bugzilla version
-use constant BUGZILLA_VERSION => "4.4.6";
+use constant BUGZILLA_VERSION => "4.4.7";
# 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.pm b/Bugzilla/DB.pm
index cf828d772..248312e12 100644
--- a/Bugzilla/DB.pm
+++ b/Bugzilla/DB.pm
@@ -577,8 +577,11 @@ sub bz_add_column {
my $current_def = $self->bz_column_info($table, $name);
if (!$current_def) {
+ # REFERENCES need to happen later and not be created right away
+ my $trimmed_def = dclone($new_def);
+ delete $trimmed_def->{REFERENCES};
my @statements = $self->_bz_real_schema->get_add_column_ddl(
- $table, $name, $new_def,
+ $table, $name, $trimmed_def,
defined $init_value ? $self->quote($init_value) : undef);
print get_text('install_column_add',
{ column => $name, table => $table }) . "\n"
@@ -592,14 +595,14 @@ sub bz_add_column {
# column exists there and has a REFERENCES item.
# bz_setup_foreign_keys will then add this FK at the end of
# Install::DB.
- my $col_abstract =
+ my $col_abstract =
$self->_bz_schema->get_column_abstract($table, $name);
if (exists $col_abstract->{REFERENCES}) {
my $new_fk = dclone($col_abstract->{REFERENCES});
$new_fk->{created} = 0;
$new_def->{REFERENCES} = $new_fk;
}
-
+
$self->_bz_real_schema->set_column($table, $name, $new_def);
$self->_bz_store_real_schema;
}
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index cebc2a4ac..32c7715b4 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -71,7 +71,7 @@ sub _throw_error {
$val = "*****" if $val =~ /password|http_pass/i;
$mesg .= "[$$] " . Data::Dumper->Dump([$val],["env($var)"]);
}
- open(ERRORLOGFID, ">>$datadir/errorlog");
+ open(ERRORLOGFID, ">>", "$datadir/errorlog");
print ERRORLOGFID "$mesg\n";
close ERRORLOGFID;
}
diff --git a/Bugzilla/FlagType.pm b/Bugzilla/FlagType.pm
index 9c20293bf..9e7ab09de 100644
--- a/Bugzilla/FlagType.pm
+++ b/Bugzilla/FlagType.pm
@@ -39,6 +39,7 @@ use Bugzilla::Util;
use Bugzilla::Group;
use Email::Address;
+use List::MoreUtils qw(uniq);
use base qw(Bugzilla::Object);
@@ -369,8 +370,6 @@ sub set_clusions {
if (!$products{$prod_id}) {
$params->{id} = $prod_id;
$products{$prod_id} = Bugzilla::Product->check($params);
- $user->in_group('editcomponents', $prod_id)
- || ThrowUserError('product_access_denied', $params);
}
$prod_name = $products{$prod_id}->name;
@@ -396,6 +395,22 @@ sub set_clusions {
$clusions{"$prod_name:$comp_name"} = "$prod_id:$comp_id";
$clusions_as_hash{$prod_id}->{$comp_id} = 1;
}
+
+ # Check the user has the editcomponent permission on products that are changing
+ if (! $user->in_group('editcomponents')) {
+ my $current_clusions = $self->$category;
+ my ($removed, $added)
+ = diff_arrays([ values %$current_clusions ], [ values %clusions ]);
+ my @changed_product_ids
+ = uniq map { substr($_, 0, index($_, ':')) } @$removed, @$added;
+ foreach my $product_id (@changed_product_ids) {
+ $user->in_group('editcomponents', $product_id)
+ || ThrowUserError('product_access_denied',
+ { name => $products{$product_id}->name });
+ }
+ }
+
+ # Set the changes
$self->{$category} = \%clusions;
$self->{"${category}_as_hash"} = \%clusions_as_hash;
$self->{"_update_$category"} = 1;
diff --git a/Bugzilla/Install/CPAN.pm b/Bugzilla/Install/CPAN.pm
index f96bb4cb9..8a880df80 100644
--- a/Bugzilla/Install/CPAN.pm
+++ b/Bugzilla/Install/CPAN.pm
@@ -203,8 +203,8 @@ sub set_cpan_config {
# Calling a senseless autoload that does nothing makes us
# automatically load any existing configuration.
# We want to avoid the "invalid command" message.
- open(my $saveout, ">&STDOUT");
- open(STDOUT, '>/dev/null');
+ open(my $saveout, ">&", "STDOUT");
+ open(STDOUT, '>', '/dev/null');
eval { CPAN->ignore_this_error_message_from_bugzilla; };
undef $@;
close(STDOUT);
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index cf61a6ec2..aac447e28 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -574,7 +574,7 @@ sub _update_old_charts {
($in_file =~ /\.orig$/i));
rename("$in_file", "$in_file.orig") or next;
- open(IN, "$in_file.orig") or next;
+ open(IN, "<", "$in_file.orig") or next;
open(OUT, '>', $in_file) or next;
# Fields in the header
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index b395b3fbf..eaab6002e 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -327,20 +327,29 @@ use constant OPERATOR_FIELD_OVERRIDE => {
# These are fields where special action is taken depending on the
# *value* passed in to the chart, sometimes.
-use constant SPECIAL_PARSING => {
- # Pronoun Fields (Ones that can accept %user%, etc.)
- assigned_to => \&_contact_pronoun,
- cc => \&_contact_pronoun,
- commenter => \&_contact_pronoun,
- qa_contact => \&_contact_pronoun,
- reporter => \&_contact_pronoun,
- 'setters.login_name' => \&_contact_pronoun,
- 'requestees.login_name' => \&_contact_pronoun,
-
- # Date Fields that accept the 1d, 1w, 1m, 1y, etc. format.
- creation_ts => \&_timestamp_translate,
- deadline => \&_timestamp_translate,
- delta_ts => \&_timestamp_translate,
+# This is a sub because custom fields are dynamic
+sub SPECIAL_PARSING {
+ my $map = {
+ # Pronoun Fields (Ones that can accept %user%, etc.)
+ assigned_to => \&_contact_pronoun,
+ cc => \&_contact_pronoun,
+ commenter => \&_contact_pronoun,
+ qa_contact => \&_contact_pronoun,
+ reporter => \&_contact_pronoun,
+ 'setters.login_name' => \&_contact_pronoun,
+ 'requestees.login_name' => \&_contact_pronoun,
+
+ # Date Fields that accept the 1d, 1w, 1m, 1y, etc. format.
+ creation_ts => \&_timestamp_translate,
+ deadline => \&_timestamp_translate,
+ delta_ts => \&_timestamp_translate,
+ };
+ foreach my $field (Bugzilla->active_custom_fields) {
+ if ($field->type == FIELD_TYPE_DATETIME) {
+ $map->{$field->name} = \&_timestamp_translate;
+ }
+ }
+ return $map;
};
# Information about fields that represent "users", used by _user_nonchanged.
diff --git a/Bugzilla/Send/Sendmail.pm b/Bugzilla/Send/Sendmail.pm
index 9513134f4..012cd6f28 100644
--- a/Bugzilla/Send/Sendmail.pm
+++ b/Bugzilla/Send/Sendmail.pm
@@ -29,7 +29,7 @@ sub send {
my $pipe = gensym;
- open($pipe, "| $mailer -t -oi @args")
+ open($pipe, "|-", "$mailer -t -oi @args")
|| return failure "Error executing $mailer: $!";
print($pipe $message->as_string)
|| return failure "Error printing via pipe to $mailer: $!";
diff --git a/Bugzilla/UserAgent.pm b/Bugzilla/UserAgent.pm
index 9f98d597c..5615f86ee 100644
--- a/Bugzilla/UserAgent.pm
+++ b/Bugzilla/UserAgent.pm
@@ -103,6 +103,7 @@ use constant OS_MAP => (
qr/\(.*Android.*\)/ => ["Android"],
# Windows
qr/\(.*Windows XP.*\)/ => ["Windows XP"],
+ qr/\(.*Windows NT 6\.4.*\)/ => ["Windows 10"],
qr/\(.*Windows NT 6\.3.*\)/ => ["Windows 8.1"],
qr/\(.*Windows NT 6\.2.*\)/ => ["Windows 8"],
qr/\(.*Windows NT 6\.1.*\)/ => ["Windows 7"],
diff --git a/Bugzilla/WebService.pm b/Bugzilla/WebService.pm
index ac4cd25ce..5646e381d 100644
--- a/Bugzilla/WebService.pm
+++ b/Bugzilla/WebService.pm
@@ -23,6 +23,10 @@ use constant LOGIN_EXEMPT => { };
# Methods that can modify data MUST not be listed here.
use constant READ_ONLY => ();
+# Whitelist of methods that a client is allowed to access when making
+# an API call.
+use constant PUBLIC_METHODS => ();
+
sub login_exempt {
my ($class, $method) = @_;
return $class->LOGIN_EXEMPT->{$method};
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index 670d234ce..419e5aac6 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -49,6 +49,24 @@ use constant READ_ONLY => qw(
search
);
+use constant PUBLIC_METHODS => qw(
+ add_attachment
+ add_comment
+ attachments
+ comments
+ create
+ fields
+ get
+ history
+ legal_values
+ possible_duplicates
+ render_comment
+ search
+ update
+ update_see_also
+ update_tags
+);
+
######################################################
# Add aliases here for old method name compatibility #
######################################################
@@ -707,19 +725,10 @@ sub add_comment {
# Append comment
$bug->add_comment($comment, { isprivate => $params->{is_private},
work_time => $params->{work_time} });
-
- # Capture the call to bug->update (which creates the new comment) in
- # a transaction so we're sure to get the correct comment_id.
-
- my $dbh = Bugzilla->dbh;
- $dbh->bz_start_transaction();
-
$bug->update();
-
- my $new_comment_id = $dbh->bz_last_key('longdescs', 'comment_id');
-
- $dbh->bz_commit_transaction();
-
+
+ my $new_comment_id = $bug->{added_comments}[0]->id;
+
# Send mail.
Bugzilla::BugMail::Send($bug->bug_id, { changer => $user });
diff --git a/Bugzilla/WebService/Bugzilla.pm b/Bugzilla/WebService/Bugzilla.pm
index 9513e4183..a6037e67e 100644
--- a/Bugzilla/WebService/Bugzilla.pm
+++ b/Bugzilla/WebService/Bugzilla.pm
@@ -31,6 +31,15 @@ use constant READ_ONLY => qw(
version
);
+use constant PUBLIC_METHODS => qw(
+ extensions
+ last_audit_time
+ parameters
+ time
+ timezone
+ version
+);
+
# Logged-out users do not need to know more than that.
use constant PARAMETERS_LOGGED_OUT => qw(
maintainer
diff --git a/Bugzilla/WebService/Classification.pm b/Bugzilla/WebService/Classification.pm
index 753b52638..f2c3ec51e 100644
--- a/Bugzilla/WebService/Classification.pm
+++ b/Bugzilla/WebService/Classification.pm
@@ -19,6 +19,10 @@ use constant READ_ONLY => qw(
get
);
+use constant PUBLIC_METHODS => qw(
+ get
+);
+
sub get {
my ($self, $params) = validate(@_, 'names', 'ids');
diff --git a/Bugzilla/WebService/Group.pm b/Bugzilla/WebService/Group.pm
index d7506aa3d..72c948aa4 100644
--- a/Bugzilla/WebService/Group.pm
+++ b/Bugzilla/WebService/Group.pm
@@ -13,6 +13,11 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::WebService::Util qw(validate translate params_to_objects);
+use constant PUBLIC_METHODS => qw(
+ create
+ update
+);
+
use constant MAPPED_RETURNS => {
userregexp => 'user_regexp',
isactive => 'is_active'
diff --git a/Bugzilla/WebService/Product.pm b/Bugzilla/WebService/Product.pm
index bb61ac434..1c8d75bb4 100644
--- a/Bugzilla/WebService/Product.pm
+++ b/Bugzilla/WebService/Product.pm
@@ -23,6 +23,15 @@ use constant READ_ONLY => qw(
get_selectable_products
);
+use constant PUBLIC_METHODS => qw(
+ create
+ get
+ get_accessible_products
+ get_enterable_products
+ get_selectable_products
+ update
+);
+
use constant MAPPED_FIELDS => {
has_unconfirmed => 'allows_unconfirmed',
is_open => 'is_active',
diff --git a/Bugzilla/WebService/Server/JSONRPC.pm b/Bugzilla/WebService/Server/JSONRPC.pm
index c2d1e8c74..aba5d310b 100644
--- a/Bugzilla/WebService/Server/JSONRPC.pm
+++ b/Bugzilla/WebService/Server/JSONRPC.pm
@@ -28,6 +28,7 @@ use Bugzilla::Util qw(correct_urlbase trim disable_utf8);
use HTTP::Message;
use MIME::Base64 qw(decode_base64 encode_base64);
+use List::MoreUtils qw(none);
#####################################
# Public JSON::RPC Method Overrides #
@@ -378,6 +379,11 @@ sub _argument_type_check {
}
}
+ # Only allowed methods to be used from our whitelist
+ if (none { $_ eq $method} $pkg->PUBLIC_METHODS) {
+ ThrowUserError('unknown_method', { method => $self->bz_method_name });
+ }
+
# This is the best time to do login checks.
$self->handle_login();
diff --git a/Bugzilla/WebService/Server/XMLRPC.pm b/Bugzilla/WebService/Server/XMLRPC.pm
index 03590bd1c..5f9cb4515 100644
--- a/Bugzilla/WebService/Server/XMLRPC.pm
+++ b/Bugzilla/WebService/Server/XMLRPC.pm
@@ -17,6 +17,9 @@ if ($ENV{MOD_PERL}) {
}
use Bugzilla::WebService::Constants;
+use Bugzilla::Error;
+
+use List::MoreUtils qw(none);
# Allow WebService methods to call XMLRPC::Lite's type method directly
BEGIN {
@@ -65,6 +68,14 @@ sub handle_login {
my ($self, $classes, $action, $uri, $method) = @_;
my $class = $classes->{$uri};
my $full_method = $uri . "." . $method;
+ # Only allowed methods to be used from the module's whitelist
+ my $file = $class;
+ $file =~ s{::}{/}g;
+ $file .= ".pm";
+ require $file;
+ if (none { $_ eq $method } $class->PUBLIC_METHODS) {
+ ThrowCodeError('unknown_method', { method => $full_method });
+ }
$self->SUPER::handle_login($class, $method, $full_method);
return;
}
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm
index b865e114c..5a7f25036 100644
--- a/Bugzilla/WebService/User.pm
+++ b/Bugzilla/WebService/User.pm
@@ -32,6 +32,15 @@ use constant READ_ONLY => qw(
get
);
+use constant PUBLIC_METHODS => qw(
+ create
+ get
+ login
+ logout
+ offer_account_by_email
+ update
+);
+
use constant MAPPED_FIELDS => {
email => 'login',
full_name => 'name',
@@ -53,27 +62,20 @@ use constant MAPPED_RETURNS => {
sub login {
my ($self, $params) = @_;
+ # Check to see if we are already logged in
+ my $user = Bugzilla->user;
+ if ($user->id) {
+ return $self->_login_to_hash($user);
+ }
+
# Username and password params are required
foreach my $param ("login", "password") {
- defined $params->{$param}
+ (defined $params->{$param} || defined $params->{'Bugzilla_' . $param})
|| ThrowCodeError('param_required', { param => $param });
}
- # Make sure the CGI user info class works if necessary.
- my $input_params = Bugzilla->input_params;
- $input_params->{'Bugzilla_login'} = $params->{login};
- $input_params->{'Bugzilla_password'} = $params->{password};
- $input_params->{'Bugzilla_restrictlogin'} = $params->{restrict_login};
-
- my $user = Bugzilla->login();
-
- my $result = { id => $self->type('int', $user->id) };
-
- if ($user->{_login_token}) {
- $result->{'token'} = $user->id . "-" . $user->{_login_token};
- }
-
- return $result;
+ $user = Bugzilla->login();
+ return $self->_login_to_hash($user);
}
sub logout {
@@ -384,6 +386,15 @@ sub _report_to_hash {
return $item;
}
+sub _login_to_hash {
+ my ($self, $user) = @_;
+ my $item = { id => $self->type('int', $user->id) };
+ if ($user->{_login_token}) {
+ $item->{'token'} = $user->id . "-" . $user->{_login_token};
+ }
+ return $item;
+}
+
1;
__END__
diff --git a/Bugzilla/WebService/Util.pm b/Bugzilla/WebService/Util.pm
index 195de79e4..c7d63b336 100644
--- a/Bugzilla/WebService/Util.pm
+++ b/Bugzilla/WebService/Util.pm
@@ -150,13 +150,13 @@ sub fix_credentials {
# even if not calling User.login. We also do not delete them as
# User.login requires "login" and "password".
if (exists $params->{'login'} && exists $params->{'password'}) {
- $params->{'Bugzilla_login'} = $params->{'login'};
- $params->{'Bugzilla_password'} = $params->{'password'};
+ $params->{'Bugzilla_login'} = delete $params->{'login'};
+ $params->{'Bugzilla_password'} = delete $params->{'password'};
}
# Allow user to pass token=12345678 as a convenience which becomes
# "Bugzilla_token" which is what the auth code looks for.
if (exists $params->{'token'}) {
- $params->{'Bugzilla_token'} = $params->{'token'};
+ $params->{'Bugzilla_token'} = delete $params->{'token'};
}
}
diff --git a/attachment.cgi b/attachment.cgi
index 7db8015a0..e003e1f12 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -549,7 +549,6 @@ sub insert {
my ($flags, $new_flags) = Bugzilla::Flag->extract_flags_from_cgi(
$bug, $attachment, $vars, SKIP_REQUESTEE_ON_ERROR);
$attachment->set_flags($flags, $new_flags);
- $attachment->update($timestamp);
# Insert a comment about the new attachment into the database.
my $comment = $cgi->param('comment');
@@ -580,6 +579,10 @@ sub insert {
$bug->add_cc($user) if $cgi->param('addselfcc');
$bug->update($timestamp);
+ # We have to update the attachment after updating the bug, to ensure new
+ # comments are available.
+ $attachment->update($timestamp);
+
$dbh->bz_commit_transaction;
# Define the variables and functions that will be passed to the UI template.
@@ -702,6 +705,11 @@ sub update {
# Figure out when the changes were made.
my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
+ # Commit the comment, if any.
+ # This has to happen before updating the attachment, to ensure new comments
+ # are available to $attachment->update.
+ $bug->update($timestamp);
+
if ($can_edit) {
my $changes = $attachment->update($timestamp);
# If there are changes, we updated delta_ts in the DB. We have to
@@ -709,9 +717,6 @@ sub update {
$bug->{delta_ts} = $timestamp if scalar(keys %$changes);
}
- # Commit the comment, if any.
- $bug->update($timestamp);
-
# Commit the transaction now that we are finished updating the database.
$dbh->bz_commit_transaction();
diff --git a/collectstats.pl b/collectstats.pl
index aa98ddfb4..d2b6b74d3 100755
--- a/collectstats.pl
+++ b/collectstats.pl
@@ -321,7 +321,7 @@ sub regenerate_stats {
return;
}
- if (open DATA, ">$file") {
+ if (open DATA, ">", $file) {
my $fields = join('|', ('DATE', @statuses, @resolutions));
print DATA <<FIN;
# Bugzilla Daily Bug Stats
diff --git a/docs/bugzilla.ent.tmpl b/docs/bugzilla.ent.tmpl
index 31e908e92..dcf5ec140 100644
--- a/docs/bugzilla.ent.tmpl
+++ b/docs/bugzilla.ent.tmpl
@@ -1,6 +1,6 @@
-<!ENTITY bz-ver "4.4.6">
-<!ENTITY bz-date "2014-10-06">
-<!ENTITY current-year "2014">
+<!ENTITY bz-ver "4.4.7">
+<!ENTITY bz-date "2015-01-21">
+<!ENTITY current-year "2015">
<!ENTITY min-perl-ver "5.8.1">
<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-4.4-branch/">
diff --git a/docs/en/xml/using.xml b/docs/en/xml/using.xml
index 04c18a795..c806da269 100644
--- a/docs/en/xml/using.xml
+++ b/docs/en/xml/using.xml
@@ -1239,11 +1239,6 @@
</listitem>
<listitem>
<para>
- Enable tags for bugs - turn bug tagging on or off.
- </para>
- </listitem>
- <listitem>
- <para>
Zoom textareas large when in use (requires JavaScript) - enable or
disable the automatic expanding of text areas when text is being
entered into them.
diff --git a/extensions/Example/lib/WebService.pm b/extensions/Example/lib/WebService.pm
index 659189d2f..56adc8cb8 100644
--- a/extensions/Example/lib/WebService.pm
+++ b/extensions/Example/lib/WebService.pm
@@ -11,6 +11,11 @@ use warnings;
use base qw(Bugzilla::WebService);
use Bugzilla::Error;
+use constant PUBLIC_METHODS => qw(
+ hello
+ throw_an_error
+);
+
# This can be called as Example.hello() from the WebService.
sub hello { return 'Hello!'; }
diff --git a/reports.cgi b/reports.cgi
index a2e1e6a7e..7b7c59478 100755
--- a/reports.cgi
+++ b/reports.cgi
@@ -136,7 +136,7 @@ sub generate_chart {
$data_file =~ s/\//-/gs;
$data_file = $dir . '/' . $data_file;
- if (! open FILE, $data_file) {
+ if (!open(FILE, '<', $data_file)) {
if ($product eq '-All-') {
$product = '';
}
diff --git a/search_plugin.cgi b/search_plugin.cgi
index 3809159c7..ca515bfae 100755
--- a/search_plugin.cgi
+++ b/search_plugin.cgi
@@ -24,7 +24,7 @@ print $cgi->header('application/xml');
# Get the contents of favicon.ico
my $filename = bz_locations()->{'libpath'} . "/images/favicon.ico";
-if (open(IN, $filename)) {
+if (open(IN, '<', $filename)) {
local $/;
binmode IN;
$vars->{'favicon'} = <IN>;
diff --git a/showdependencygraph.cgi b/showdependencygraph.cgi
index 8e3592fbe..4187bdd4e 100755
--- a/showdependencygraph.cgi
+++ b/showdependencygraph.cgi
@@ -46,7 +46,7 @@ sub CreateImagemap {
my $map = "<map name=\"imagemap\">\n";
my $default = "";
- open MAP, "<$mapfilename";
+ open MAP, "<", $mapfilename;
while(my $line = <MAP>) {
if($line =~ /^default ([^ ]*)(.*)$/) {
$default = qq{<area alt="" shape="default" href="$1">\n};
@@ -247,7 +247,7 @@ if ($webdotbase =~ /^https?:/) {
error => $! });
binmode $pngfh;
- open(DOT, "\"$webdotbase\" -Tpng $filename|");
+ open(DOT, '-|', "\"$webdotbase\" -Tpng $filename");
binmode DOT;
print $pngfh $_ while <DOT>;
close DOT;
@@ -276,7 +276,7 @@ if ($webdotbase =~ /^https?:/) {
error => $! });
binmode $mapfh;
- open(DOT, "\"$webdotbase\" -Tismap $filename|");
+ open(DOT, '-|', "\"$webdotbase\" -Tismap $filename");
binmode DOT;
print $mapfh $_ while <DOT>;
close DOT;
diff --git a/template/en/default/bug/dependency-tree.html.tmpl b/template/en/default/bug/dependency-tree.html.tmpl
index a4bb0e672..f53663685 100644
--- a/template/en/default/bug/dependency-tree.html.tmpl
+++ b/template/en/default/bug/dependency-tree.html.tmpl
@@ -152,9 +152,12 @@
[% END %]
[% BLOCK buginfo %]
- [% display_value("bug_status", bug.bug_status) FILTER html -%] [%+ display_value("resolution", bug.resolution) FILTER html %];
+ [% display_value("bug_status", bug.bug_status) FILTER html -%]
+ [%- IF bug.resolution %] [%+ display_value("resolution", bug.resolution) FILTER html %][% END %];
[%-%] assigned to [% bug.assigned_to.login FILTER email FILTER html %]
- [%-%][% "; Target: " _ bug.target_milestone IF bug.target_milestone %]
+ [% IF Param("usetargetmilestone") AND bug.target_milestone %]
+ [%-%]; target: [% bug.target_milestone FILTER html %]
+ [% END %]
[% END %]
[%###########################################################################%]
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index 086f34ab6..e4416326b 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -219,7 +219,8 @@
but rather <em>[% target_type FILTER html %]</em>.
[% ELSIF error == "invalid_field_name" %]
- Can't use [% field FILTER html %] as a field name.
+ [% title = "Invalid Field Name" %]
+ Can't use "[% field.truncate(30, "...") FILTER html %]" as a field name.
[% ELSIF error == "jobqueue_insert_failed" %]
[% title = "Job Queue Failure" %]
@@ -384,8 +385,9 @@
Invalid setting for post_bug_submit_action
[% ELSIF error == "search_field_operator_unsupported" %]
+ [% title = "Invalid Search Type" %]
[% terms.Bugzilla %] does not support the search type
- "[% operator FILTER html %]".
+ "[% operator.truncate(30, "...") FILTER html %]".
[% ELSE %]
[%# Try to find hooked error messages %]
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 8dbcd45e3..492c2ad4b 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -1725,10 +1725,11 @@
then try again.
[% ELSIF error == "unknown_action" %]
+ [% title = "Unknown Action" %]
[% IF action %]
- Unknown action [% action FILTER html %]!
+ Unknown action "[% action.truncate(20, "...") FILTER html %]"!
[% ELSE %]
- I could not figure out what you wanted to do.
+ I could not figure out what you wanted to do.
[% END %]
[% ELSIF error == "unknown_tab" %]
diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl
index 5c11360f3..bafd9184a 100644
--- a/template/en/default/pages/release-notes.html.tmpl
+++ b/template/en/default/pages/release-notes.html.tmpl
@@ -45,6 +45,25 @@
<h2 id="v44_point">Updates in this 4.4.x Release</h2>
+<h3>4.4.7</h3>
+
+<p>This release contains fixes for a couple of security issues.
+ See the <a href="https://www.bugzilla.org/security/4.0.15/">
+ Security Advisory</a> for details.</p>
+
+<p>In addition, the following important fixes have been made in the release:</p>
+
+<ul>
+ <li>The <kbd>B[%%]ug.add_comment</kbd> WebService method now returns the correct
+ ID for the newly created [% terms.bug %] comment.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1111043">[% terms.Bug %] 1111043</a>)</li>
+ <li>Fixing a regression caused by CVE-2014-1571
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1064140">[% terms.bug %] 1064140</a>),
+ comments made while setting a flag from the attachment details page are again
+ included in the flag notification email.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1082887">[% terms.Bug %] 1082887</a>)</li>
+</ul>
+
<h3>4.4.6</h3>
<p>This release fixes several security issues. See the
@@ -2317,7 +2336,7 @@
[% BLOCK db_req %]
[% SET m = DB_MODULE.$db %]
- <h3 id="v40_req_[% db FILTER html %]">For [% m.name FILTER html %] Users</h3>
+ <h3 id="v44_req_[% db FILTER html %]">For [% m.name FILTER html %] Users</h3>
<ul>
<li>[% m.name FILTER html %]
diff --git a/testserver.pl b/testserver.pl
index 77489d252..12cdfe5f0 100755
--- a/testserver.pl
+++ b/testserver.pl
@@ -37,7 +37,7 @@ my @pscmds = ('ps -eo comm,gid', 'ps -acxo command,gid', 'ps -acxo command,rgid'
my $sgid = 0;
if (!ON_WINDOWS) {
foreach my $pscmd (@pscmds) {
- open PH, "$pscmd 2>/dev/null |";
+ open PH, '-|', "$pscmd 2>/dev/null";
while (my $line = <PH>) {
if ($line =~ /^(?:\S*\/)?(?:httpd|apache?)2?\s+(\d+)$/) {
$sgid = $1 if $1 > $sgid;
@@ -264,7 +264,7 @@ sub check_image {
sub create_file {
my ($filename, $content) = @_;
- open(FH, ">$filename")
+ open(FH, ">", $filename)
or die "Failed to create $filename: $!\n";
binmode FH;
print FH $content;
@@ -273,7 +273,7 @@ sub create_file {
sub read_file {
my ($filename) = @_;
- open(FH, $filename)
+ open(FH, '<', $filename)
or die "Failed to open $filename: $!\n";
binmode FH;
my $content = <FH>;