diff options
author | Robin H. Johnson <robbat2@gentoo.org> | 2015-02-07 10:46:12 -0800 |
---|---|---|
committer | Robin H. Johnson <robbat2@gentoo.org> | 2015-02-07 10:46:12 -0800 |
commit | 6f8a072654b599c6a316898fedb917445ec46f5e (patch) | |
tree | 4f4fc6b9411b766ffada0a9c02ab510b5dc8969b | |
parent | Merge tag 'bugzilla-4.4.6' into upstream (diff) | |
parent | Bumped version to 4.4.7 (diff) | |
download | bugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.tar.gz bugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.tar.bz2 bugzilla-6f8a072654b599c6a316898fedb917445ec46f5e.zip |
Merge tag 'release-4.4.7' into upstream
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>; |