Remove docs changes by jwilmoth@starbucks.com.

git-svn-id: svn://10.0.0.236/trunk@265700 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzrmirror%bugzilla.org 2014-12-03 22:02:31 +00:00
parent 7cc2d5e854
commit 200d60ec4d
378 changed files with 1473 additions and 8967 deletions

View File

@ -1 +1 @@
9229
9230

View File

@ -1 +1 @@
c0dbbc6e69bdefcb49fd9046f7e830880d3ac513
1d69e313176b3744e144d3fb8cc58664334cef17

View File

@ -29,6 +29,5 @@ Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
RewriteRule ^rest/(.*)$ rest.cgi/$1 [NE]
</IfModule>

View File

@ -8,10 +8,7 @@ perl:
env:
- TEST_SUITE=sanity
- TEST_SUITE=docs
- TEST_SUITE=webservices DB=mysql
- TEST_SUITE=selenium DB=mysql
- TEST_SUITE=webservices DB=pg
- TEST_SUITE=selenium DB=pg
- TEST_SUITE=checksetup DB=mysql
matrix:
exclude:
@ -22,32 +19,14 @@ matrix:
- perl: 5.14
env: TEST_SUITE=docs
- perl: 5.10
env: TEST_SUITE=webservices DB=mysql
- perl: 5.10
env: TEST_SUITE=webservices DB=pg
- perl: 5.10
env: TEST_SUITE=selenium DB=mysql
- perl: 5.10
env: TEST_SUITE=selenium DB=pg
env: TEST_SUITE=checksetup DB=mysql
- perl: 5.12
env: TEST_SUITE=webservices DB=mysql
- perl: 5.12
env: TEST_SUITE=webservices DB=pg
- perl: 5.12
env: TEST_SUITE=selenium DB=mysql
- perl: 5.12
env: TEST_SUITE=selenium DB=pg
env: TEST_SUITE=checksetup DB=mysql
- perl: 5.14
env: TEST_SUITE=webservices DB=mysql
- perl: 5.14
env: TEST_SUITE=webservices DB=pg
- perl: 5.14
env: TEST_SUITE=selenium DB=mysql
- perl: 5.14
env: TEST_SUITE=selenium DB=pg
env: TEST_SUITE=checksetup DB=mysql
before_install:
- git clone https://github.com/bugzilla/qa.git -b master qa
- git clone https://github.com/bugzilla/qa.git -b 4.4 qa
install: true

View File

@ -9,7 +9,6 @@ package Bugzilla;
use 5.10.1;
use strict;
use warnings;
# We want any compile errors to get to the browser, if possible.
BEGIN {
@ -122,8 +121,8 @@ sub init_page {
#
# This code must go here. It cannot go anywhere in Bugzilla::CGI, because
# it uses Template, and that causes various dependency loops.
if (!grep { $_ eq $script } SHUTDOWNHTML_EXEMPT
and Bugzilla->params->{'shutdownhtml'})
if (Bugzilla->params->{"shutdownhtml"}
&& !grep { $_ eq $script } SHUTDOWNHTML_EXEMPT)
{
# Allow non-cgi scripts to exit silently (without displaying any
# message), if desired. At this point, no DBI call has been made
@ -397,13 +396,6 @@ sub logout_request {
# there. Don't rely on it: use Bugzilla->user->login instead!
}
sub markdown {
return if !Bugzilla->feature('markdown');
require Bugzilla::Markdown;
return $_[0]->request_cache->{markdown} ||= Bugzilla::Markdown->new();
}
sub job_queue {
require Bugzilla::JobQueue;
return $_[0]->request_cache->{job_queue} ||= Bugzilla::JobQueue->new();
@ -659,16 +651,13 @@ sub memcached {
# Per-process cleanup. Note that this is a plain subroutine, not a method,
# so we don't have $class available.
sub _cleanup {
my $cache = Bugzilla->request_cache;
my $main = $cache->{dbh_main};
my $shadow = $cache->{dbh_shadow};
my $main = Bugzilla->request_cache->{dbh_main};
my $shadow = Bugzilla->request_cache->{dbh_shadow};
foreach my $dbh ($main, $shadow) {
next if !$dbh;
$dbh->bz_rollback_transaction() if $dbh->bz_in_transaction;
$dbh->disconnect;
}
my $smtp = $cache->{smtp};
$smtp->disconnect if $smtp;
clear_request_cache();
# These are both set by CGI.pm but need to be undone so that
@ -760,7 +749,7 @@ If you ever need a L<Bugzilla::Template> object while you're already
processing a template, use this. Also use it if you want to specify
the language to use. If no argument is passed, it uses the last
language set. If the argument is "" (empty string), the language is
reset to the current one (the one used by C<Bugzilla-E<gt>template>).
reset to the current one (the one used by Bugzilla->template).
=item C<cgi>
@ -878,8 +867,8 @@ specify this argument, all fields will be returned.
=item C<error_mode>
Call either C<Bugzilla-E<gt>error_mode(Bugzilla::Constants::ERROR_MODE_DIE)>
or C<Bugzilla-E<gt>error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to
Call either C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE)>
or C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to
change this flag's default of C<Bugzilla::Constants::ERROR_MODE_WEBPAGE> and to
indicate that errors should be passed to error mode specific error handlers
rather than being sent to a browser and finished with an exit().
@ -888,24 +877,24 @@ This is useful, for example, to keep C<eval> blocks from producing wild HTML
on errors, making it easier for you to catch them.
(Remember to reset the error mode to its previous value afterwards, though.)
C<Bugzilla-E<gt>error_mode> will return the current state of this flag.
C<Bugzilla->error_mode> will return the current state of this flag.
Note that C<Bugzilla-E<gt>error_mode> is being called by C<Bugzilla-E<gt>usage_mode> on
Note that C<Bugzilla->error_mode> is being called by C<Bugzilla->usage_mode> on
usage mode changes.
=item C<usage_mode>
Call either C<Bugzilla-E<gt>usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)>
or C<Bugzilla-E<gt>usage_mode(Bugzilla::Constants::USAGE_MODE_XMLRPC)> near the
Call either C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)>
or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_XMLRPC)> near the
beginning of your script to change this flag's default of
C<Bugzilla::Constants::USAGE_MODE_BROWSER> and to indicate that Bugzilla is
being called in a non-interactive manner.
This influences error handling because on usage mode changes, C<usage_mode>
calls C<Bugzilla-E<gt>error_mode> to set an error mode which makes sense for the
calls C<Bugzilla->error_mode> to set an error mode which makes sense for the
usage mode.
C<Bugzilla-E<gt>usage_mode> will return the current state of this flag.
C<Bugzilla->usage_mode> will return the current state of this flag.
=item C<installation_mode>
@ -944,9 +933,9 @@ Change the database object to refer to the main database.
=item C<params>
The current Parameters of Bugzilla, as a hashref. If C<data/params.json>
does not exist, then we return an empty hashref. If C<data/params.json>
is unreadable or is not valid, we C<die>.
The current Parameters of Bugzilla, as a hashref. If C<data/params>
does not exist, then we return an empty hashref. If C<data/params>
is unreadable or is not valid perl, we C<die>.
=item C<local_timezone>
@ -954,10 +943,6 @@ Returns the local timezone of the Bugzilla installation,
as a DateTime::TimeZone object. This detection is very time
consuming, so we cache this information for future references.
=item C<markdown>
The current L<Markdown|Bugzilla::Markdown> object, to be used for Markdown rendering.
=item C<job_queue>
Returns a L<Bugzilla::JobQueue> that you can use for queueing jobs.

View File

@ -9,7 +9,6 @@ package Bugzilla::Attachment;
use 5.10.1;
use strict;
use warnings;
=head1 NAME
@ -308,8 +307,7 @@ sub is_viewable {
=item C<data>
Returns the content of the attachment.
As a side-effect, sets $self->is_on_filesystem.
the content of the attachment
=back
@ -326,16 +324,10 @@ sub data {
undef,
$self->id);
# Setting the property here is cheap, as opposed to making an extra
# query later, and hitting the filesystem to see if the file is
# still there.
$self->{is_on_filesystem} = 0;
# 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())) {
# file is actually on disk.
$self->{is_on_filesystem} = 1;
local $/;
binmode AH;
$self->{data} = <AH>;
@ -348,36 +340,9 @@ sub data {
=over
=item C<is_on_filesystem>
Returns true if the attachment is stored on disk (via maxlocalattachment
parameter), as opposed to in the database.
=back
=cut
# When the attachment is on the filesystem, you can let the backend
# (nginx, apache, lighttpd) serve it for you if it supports the X-Sendfile
# feature. This means that the attachment CGI script may have a reduced
# footprint. e.g. bug 906010 and bug 1073241.
sub is_on_filesystem {
my $self = shift;
return $self->{is_on_filesystem} if exists $self->{is_on_filesystem};
# In order to serve an attachment, you also send the datasize in the
# content-length header. Making additional queries which are exactly
# the same as found in the datasize code path is just wasteful.
my $datasize = $self->datasize;
return $self->{is_on_filesystem};
}
=over
=item C<datasize>
Returns the length (in bytes) of the attachment content.
As a side-effect, sets $self->is_on_filesystem.
the length (in bytes) of the attachment content
=back
@ -404,17 +369,11 @@ sub datasize {
WHERE id = ?",
undef, $self->id) || 0;
# Setting the property here is cheap, as opposed to making an extra
# query later, and hitting the filesystem to see if the file is
# still there.
$self->{is_on_filesystem} = 0;
# If there's no attachment data in the database, either the attachment
# 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())) {
# file is actually on disk.
$self->{is_on_filesystem} = 1;
binmode AH;
$self->{datasize} = (stat(AH))[7];
close(AH);

View File

@ -9,7 +9,6 @@ package Bugzilla::Attachment::PatchReader;
use 5.10.1;
use strict;
use warnings;
use Config;
use IO::Select;
@ -23,18 +22,17 @@ use Bugzilla::Util;
use constant PERLIO_IS_ENABLED => $Config{useperlio};
sub process_diff {
my ($attachment, $format) = @_;
my ($attachment, $format, $context) = @_;
my $dbh = Bugzilla->dbh;
my $cgi = Bugzilla->cgi;
my $lc = Bugzilla->localconfig;
my $vars = {};
require PatchReader::Raw;
my $reader = new PatchReader::Raw;
my ($reader, $last_reader) = setup_patch_readers(undef, $context);
if ($format eq 'raw') {
require PatchReader::DiffPrinter::raw;
$reader->sends_data_to(new PatchReader::DiffPrinter::raw());
$last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
# Actually print out the patch.
print $cgi->header(-type => 'text/plain');
disable_utf8();
@ -72,7 +70,7 @@ sub process_diff {
$vars->{'description'} = $attachment->description;
$vars->{'other_patches'} = \@other_patches;
setup_template_patch_reader($reader, $vars);
setup_template_patch_reader($last_reader, $format, $context, $vars);
# The patch is going to be displayed in a HTML page and if the utf8
# param is enabled, we have to encode attachment data as utf8.
if (Bugzilla->params->{'utf8'}) {
@ -84,13 +82,11 @@ sub process_diff {
}
sub process_interdiff {
my ($old_attachment, $new_attachment, $format) = @_;
my ($old_attachment, $new_attachment, $format, $context) = @_;
my $cgi = Bugzilla->cgi;
my $lc = Bugzilla->localconfig;
my $vars = {};
require PatchReader::Raw;
# Encode attachment data as utf8 if it's going to be displayed in a HTML
# page using the UTF-8 encoding.
if ($format ne 'raw' && Bugzilla->params->{'utf8'}) {
@ -180,11 +176,10 @@ sub process_interdiff {
$warning = 'interdiff3';
}
my $reader = new PatchReader::Raw;
my ($reader, $last_reader) = setup_patch_readers("", $context);
if ($format eq 'raw') {
require PatchReader::DiffPrinter::raw;
$reader->sends_data_to(new PatchReader::DiffPrinter::raw());
$last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
# Actually print out the patch.
print $cgi->header(-type => 'text/plain');
disable_utf8();
@ -197,7 +192,7 @@ sub process_interdiff {
$vars->{'newid'} = $new_attachment->id;
$vars->{'new_desc'} = $new_attachment->description;
setup_template_patch_reader($reader, $vars);
setup_template_patch_reader($last_reader, $format, $context, $vars);
}
$reader->iterate_string('interdiff #' . $old_attachment->id .
' #' . $new_attachment->id, $stdout);
@ -212,6 +207,7 @@ sub get_unified_diff {
# Bring in the modules we need.
require PatchReader::Raw;
require PatchReader::FixPatchRoot;
require PatchReader::DiffPrinter::raw;
require PatchReader::PatchInfoGrabber;
require File::Temp;
@ -223,6 +219,14 @@ sub get_unified_diff {
my $reader = new PatchReader::Raw;
my $last_reader = $reader;
# Fixes patch root (makes canonical if possible).
if (Bugzilla->params->{'cvsroot'}) {
my $fix_patch_root =
new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'});
$last_reader->sends_data_to($fix_patch_root);
$last_reader = $fix_patch_root;
}
# Grabs the patch file info.
my $patch_info_grabber = new PatchReader::PatchInfoGrabber();
$last_reader->sends_data_to($patch_info_grabber);
@ -269,8 +273,46 @@ sub warn_if_interdiff_might_fail {
return undef;
}
sub setup_patch_readers {
my ($diff_root, $context) = @_;
# Parameters:
# format=raw|html
# context=patch|file|0-n
# collapsed=0|1
# headers=0|1
# Define the patch readers.
# The reader that reads the patch in (whatever its format).
require PatchReader::Raw;
my $reader = new PatchReader::Raw;
my $last_reader = $reader;
# Fix the patch root if we have a cvs root.
if (Bugzilla->params->{'cvsroot'}) {
require PatchReader::FixPatchRoot;
$last_reader->sends_data_to(new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'}));
$last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root);
$last_reader = $last_reader->sends_data_to;
}
# Add in cvs context if we have the necessary info to do it
if ($context ne 'patch' && Bugzilla->localconfig->{cvsbin}
&& Bugzilla->params->{'cvsroot_get'})
{
require PatchReader::AddCVSContext;
# We need to set $cvsbin as global, because PatchReader::CVSClient
# needs it in order to find 'cvs'.
$main::cvsbin = Bugzilla->localconfig->{cvsbin};
$last_reader->sends_data_to(
new PatchReader::AddCVSContext($context, Bugzilla->params->{'cvsroot_get'}));
$last_reader = $last_reader->sends_data_to;
}
return ($reader, $last_reader);
}
sub setup_template_patch_reader {
my ($last_reader, $vars) = @_;
my ($last_reader, $format, $context, $vars) = @_;
my $cgi = Bugzilla->cgi;
my $template = Bugzilla->template;
@ -285,15 +327,22 @@ sub setup_template_patch_reader {
}
$vars->{'collapsed'} = $cgi->param('collapsed');
$vars->{'context'} = $context;
$vars->{'do_context'} = Bugzilla->localconfig->{cvsbin}
&& Bugzilla->params->{'cvsroot_get'} && !$vars->{'newid'};
# Print everything out.
print $cgi->header(-type => 'text/html');
$last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template,
'attachment/diff-header.html.tmpl',
'attachment/diff-file.html.tmpl',
'attachment/diff-footer.html.tmpl',
$vars));
"attachment/diff-header.$format.tmpl",
"attachment/diff-file.$format.tmpl",
"attachment/diff-footer.$format.tmpl",
{ %{$vars},
bonsai_url => Bugzilla->params->{'bonsai_url'},
lxr_url => Bugzilla->params->{'lxr_url'},
lxr_root => Bugzilla->params->{'lxr_root'},
}));
}
1;
@ -314,4 +363,6 @@ __END__
=item process_interdiff
=item setup_patch_readers
=back

View File

@ -9,8 +9,6 @@ package Bugzilla::Auth;
use 5.10.1;
use strict;
use warnings;
use fields qw(
_info_getter
_verifier
@ -32,7 +30,7 @@ sub new {
my $self = fields::new($class);
$params ||= {};
$params->{Login} ||= Bugzilla->params->{'user_info_class'} . ',Cookie,APIKey';
$params->{Login} ||= Bugzilla->params->{'user_info_class'} . ',Cookie';
$params->{Verify} ||= Bugzilla->params->{'user_verify_class'};
$self->{_info_getter} = new Bugzilla::Auth::Login::Stack($params->{Login});
@ -46,6 +44,7 @@ sub new {
sub login {
my ($self, $type) = @_;
my $dbh = Bugzilla->dbh;
# Get login info from the cookie, form, environment variables, etc.
my $login_info = $self->{_info_getter}->get_login_info();

View File

@ -9,8 +9,6 @@ package Bugzilla::Auth::Login;
use 5.10.1;
use strict;
use warnings;
use fields qw();
# Determines whether or not a user can logout. It's really a subroutine,

View File

@ -1,53 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
package Bugzilla::Auth::Login::APIKey;
use 5.10.1;
use strict;
use warnings;
use base qw(Bugzilla::Auth::Login);
use Bugzilla::Constants;
use Bugzilla::User::APIKey;
use Bugzilla::Util;
use Bugzilla::Error;
use constant requires_persistence => 0;
use constant requires_verification => 0;
use constant can_login => 0;
use constant can_logout => 0;
# This method is only available to web services. An API key can never
# be used to authenticate a Web request.
sub get_login_info {
my ($self) = @_;
my $params = Bugzilla->input_params;
my ($user_id, $login_cookie);
my $api_key_text = trim(delete $params->{'Bugzilla_api_key'});
if (!i_am_webservice() || !$api_key_text) {
return { failure => AUTH_NODATA };
}
my $api_key = Bugzilla::User::APIKey->new({ name => $api_key_text });
if (!$api_key or $api_key->api_key ne $api_key_text) {
# The second part checks the correct capitalisation. Silly MySQL
ThrowUserError("api_key_not_valid");
}
elsif ($api_key->revoked) {
ThrowUserError('api_key_revoked');
}
$api_key->update_last_used();
return { user_id => $api_key->user_id };
}
1;

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Login::CGI;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Login);
use constant user_can_create_account => 1;

View File

@ -9,15 +9,13 @@ package Bugzilla::Auth::Login::Cookie;
use 5.10.1;
use strict;
use warnings;
use base qw(Bugzilla::Auth::Login);
use fields qw(_login_token);
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Token;
use Bugzilla::Util;
use Bugzilla::Error;
use List::Util qw(first);
@ -51,20 +49,6 @@ sub get_login_info {
@{$cgi->{'Bugzilla_cookie_list'}};
$user_id = $cookie->value if $cookie;
}
# If the call is for a web service, and an api token is provided, check
# it is valid.
if (i_am_webservice() && Bugzilla->input_params->{Bugzilla_api_token}) {
my $api_token = Bugzilla->input_params->{Bugzilla_api_token};
my ($token_user_id, undef, undef, $token_type)
= Bugzilla::Token::GetTokenData($api_token);
if (!defined $token_type
|| $token_type ne 'api_token'
|| $user_id != $token_user_id)
{
ThrowUserError('auth_invalid_token', { token => $api_token });
}
}
}
# If no cookies were provided, we also look for a login token

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Login::Env;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Login);
@ -25,6 +24,7 @@ use constant extern_id_used => 1;
sub get_login_info {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
my $env_id = $ENV{Bugzilla->params->{"auth_env_id"}} || '';
my $env_email = $ENV{Bugzilla->params->{"auth_env_email"}} || '';

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Login::Stack;
use 5.10.1;
use strict;
use warnings;
use base qw(Bugzilla::Auth::Login);
use fields qw(

View File

@ -9,8 +9,6 @@ package Bugzilla::Auth::Persist::Cookie;
use 5.10.1;
use strict;
use warnings;
use fields qw();
use Bugzilla::Constants;

View File

@ -9,8 +9,6 @@ package Bugzilla::Auth::Verify;
use 5.10.1;
use strict;
use warnings;
use fields qw();
use Bugzilla::Constants;

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Verify::DB;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Verify);
@ -56,19 +55,10 @@ sub check_credentials {
};
}
# Force the user to change their password if it does not meet the current
# criteria. This should usually only happen if the criteria has changed.
if (Bugzilla->usage_mode == USAGE_MODE_BROWSER &&
Bugzilla->params->{password_check_on_login})
{
my $check = validate_password_check($password);
if ($check) {
return {
failure => AUTH_ERROR,
user_error => $check,
details => { locked_user => $user }
}
}
# Force the user to type a longer password if it's too short.
if (length($password) < USER_PASSWORD_MIN_LENGTH) {
return { failure => AUTH_ERROR, user_error => 'password_current_too_short',
details => { locked_user => $user } };
}
# The user's credentials are okay, so delete any outstanding

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Verify::LDAP;
use 5.10.1;
use strict;
use warnings;
use base qw(Bugzilla::Auth::Verify);
use fields qw(

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Verify::RADIUS;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Verify);

View File

@ -9,7 +9,6 @@ package Bugzilla::Auth::Verify::Stack;
use 5.10.1;
use strict;
use warnings;
use base qw(Bugzilla::Auth::Verify);
use fields qw(

View File

@ -9,7 +9,6 @@ package Bugzilla::Bug;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Attachment;
use Bugzilla::Constants;
@ -49,7 +48,7 @@ use parent qw(Bugzilla::Object Exporter);
use constant DB_TABLE => 'bugs';
use constant ID_FIELD => 'bug_id';
use constant NAME_FIELD => 'bug_id';
use constant NAME_FIELD => 'alias';
use constant LIST_ORDER => ID_FIELD;
# Bugs have their own auditing table, bugs_activity.
use constant AUDIT_CREATES => 0;
@ -65,6 +64,7 @@ sub DB_COLUMNS {
my @custom_names = map {$_->name} @custom;
my @columns = (qw(
alias
assigned_to
bug_file_loc
bug_id
@ -207,6 +207,7 @@ sub UPDATE_COLUMNS {
Bugzilla->active_custom_fields;
my @custom_names = map {$_->name} @custom;
my @columns = qw(
alias
assigned_to
bug_file_loc
bug_severity
@ -312,20 +313,11 @@ sub new {
# 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 =~ /\D/)
|| (ref($param) && $param->{id} =~ /\D/))
{
if ($param) {
my $alias = ref($param) ? $param->{id} : $param;
my $bug_id = bug_alias_to_id($alias);
if (! $bug_id) {
my $error_self = {};
bless $error_self, $class;
$error_self->{'bug_id'} = $alias;
$error_self->{'error'} = 'InvalidBugId';
return $error_self;
}
$param = { id => $bug_id,
$param = { name => ref($param) ? $param->{id} : $param,
cache => ref($param) ? $param->{cache} : 0 };
}
else {
@ -555,9 +547,6 @@ sub _preload_referenced_bugs {
foreach my $bug (@$referenced_bugs) {
$bug->object_cache_set();
}
# preload bug visibility
Bugzilla->user->visible_bugs(\@referenced_bug_ids);
}
sub possible_duplicates {
@ -694,22 +683,18 @@ sub create {
unless defined $params->{rep_platform};
# Make sure a comment is always defined.
$params->{comment} = '' unless defined $params->{comment};
$params->{is_markdown} = 0
unless defined $params->{is_markdown} && $params->{is_markdown} eq '1';
$class->check_required_create_fields($params);
$params = $class->run_create_validators($params);
# These are not a fields in the bugs table, so we don't pass them to
# insert_create_data.
my $bug_aliases = delete $params->{alias};
my $cc_ids = delete $params->{cc};
my $groups = delete $params->{groups};
my $depends_on = delete $params->{dependson};
my $blocked = delete $params->{blocked};
my $keywords = delete $params->{keywords};
my $creation_comment = delete $params->{comment};
my $is_markdown = delete $params->{is_markdown};
my $see_also = delete $params->{see_also};
# We don't want the bug to appear in the system until it's correctly
@ -797,19 +782,11 @@ sub create {
# We now have a bug id so we can fill this out
$creation_comment->{'bug_id'} = $bug->id;
$creation_comment->{'is_markdown'} = $is_markdown;
# Insert the comment. We always insert a comment on bug creation,
# but sometimes it's blank.
Bugzilla::Comment->insert_create_data($creation_comment);
# Set up aliases
my $sth_aliases = $dbh->prepare('INSERT INTO bugs_aliases (alias, bug_id) VALUES (?, ?)');
foreach my $alias (@$bug_aliases) {
trick_taint($alias);
$sth_aliases->execute($alias, $bug->bug_id);
}
Bugzilla::Hook::process('bug_end_of_create', { bug => $bug,
timestamp => $timestamp,
});
@ -929,26 +906,7 @@ sub update {
my $added_names = join(', ', (map {$_->login} @$added_users));
$changes->{cc} = [$removed_names, $added_names];
}
# Aliases
my $old_aliases = $old_bug->alias;
my $new_aliases = $self->alias;
my ($removed_aliases, $added_aliases) = diff_arrays($old_aliases, $new_aliases);
foreach my $alias (@$removed_aliases) {
$dbh->do('DELETE FROM bugs_aliases WHERE bug_id = ? AND alias = ?',
undef, $self->id, $alias);
}
foreach my $alias (@$added_aliases) {
trick_taint($alias);
$dbh->do('INSERT INTO bugs_aliases (bug_id, alias) VALUES (?,?)',
undef, $self->id, $alias);
}
# If any changes were found, record it in the activity log
if (scalar @$removed_aliases || scalar @$added_aliases) {
$changes->{alias} = [join(', ', @$removed_aliases), join(', ', @$added_aliases)];
}
# Keywords
my @old_kw_ids = map { $_->id } @{$old_bug->keyword_objects};
my @new_kw_ids = map { $_->id } @{$self->keyword_objects};
@ -1030,6 +988,12 @@ sub update {
join(', ', @added_names)];
}
# Flags
my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_bug, $delta_ts);
if ($removed || $added) {
$changes->{'flagtypes.name'} = [$removed, $added];
}
# Comments
foreach my $comment (@{$self->{added_comments} || []}) {
# Override the Comment's timestamp to be identical to the update
@ -1052,9 +1016,6 @@ sub update {
$user->id, $delta_ts, $comment->id);
}
# Clear the cache of comments
delete $self->{comments};
# Insert the values into the multiselect value tables
my @multi_selects = grep {$_->type == FIELD_TYPE_MULTI_SELECT}
Bugzilla->active_custom_fields;
@ -1087,12 +1048,6 @@ sub update {
join(', ', map { $_->name } @$added_see)];
}
# Flags
my ($removed, $added) = Bugzilla::Flag->update_flags($self, $old_bug, $delta_ts);
if ($removed || $added) {
$changes->{'flagtypes.name'} = [$removed, $added];
}
$_->update foreach @{ $self->{_update_ref_bugs} || [] };
delete $self->{_update_ref_bugs};
@ -1140,13 +1095,6 @@ sub update {
$self->update_user_last_visit($user, $delta_ts);
}
# If a user is no longer involved, remove their last visit entry
my $last_visits =
Bugzilla::BugUserLastVisit->match({ bug_id => $self->id });
foreach my $lv (@$last_visits) {
$lv->remove_from_db() unless $lv->user->is_involved_in_bug($self);
}
# Update bug ignore data if user wants to ignore mail for this bug
if (exists $self->{'bug_ignored'}) {
my $bug_ignored_changed;
@ -1362,38 +1310,32 @@ sub _send_bugmail {
#####################################################################
sub _check_alias {
my ($invocant, $aliases) = @_;
$aliases = ref $aliases ? $aliases : [split(/[\s,]+/, $aliases)];
my ($invocant, $alias) = @_;
$alias = trim($alias);
return undef if (!$alias);
# Remove empty aliases
@$aliases = grep { $_ } @$aliases;
foreach my $alias (@$aliases) {
$alias = trim($alias);
# Make sure the alias isn't too long.
if (length($alias) > 40) {
ThrowUserError("alias_too_long");
}
# Make sure the alias isn't just a number.
if ($alias =~ /^\d+$/) {
ThrowUserError("alias_is_numeric", { alias => $alias });
}
# Make sure the alias has no commas or spaces.
if ($alias =~ /[, ]/) {
ThrowUserError("alias_has_comma_or_space", { alias => $alias });
}
# Make sure the alias is unique, or that it's already our alias.
my $other_bug = new Bugzilla::Bug($alias);
if (!$other_bug->{error}
&& (!ref $invocant || $other_bug->id != $invocant->id))
{
ThrowUserError("alias_in_use", { alias => $alias,
bug_id => $other_bug->id });
}
# Make sure the alias isn't too long.
if (length($alias) > 20) {
ThrowUserError("alias_too_long");
}
# Make sure the alias isn't just a number.
if ($alias =~ /^\d+$/) {
ThrowUserError("alias_is_numeric", { alias => $alias });
}
# Make sure the alias has no commas or spaces.
if ($alias =~ /[, ]/) {
ThrowUserError("alias_has_comma_or_space", { alias => $alias });
}
# Make sure the alias is unique, or that it's already our alias.
my $other_bug = new Bugzilla::Bug($alias);
if (!$other_bug->{error}
&& (!ref $invocant || $other_bug->id != $invocant->id))
{
ThrowUserError("alias_in_use", { alias => $alias,
bug_id => $other_bug->id });
}
return $aliases;
return $alias;
}
sub _check_assigned_to {
@ -2430,15 +2372,7 @@ sub set_all {
# there are lots of things that want to check if we added a comment.
$self->add_comment($params->{'comment'}->{'body'},
{ isprivate => $params->{'comment'}->{'is_private'},
work_time => $params->{'work_time'},
is_markdown => $params->{'comment'}->{'is_markdown'} });
}
if (exists $params->{alias} && $params->{alias}{set}) {
$params->{alias} = {
add => $params->{alias}{set},
remove => $self->alias,
};
work_time => $params->{'work_time'} });
}
my %normal_set_all;
@ -2465,7 +2399,6 @@ sub set_all {
}
$self->_add_remove($params, 'cc');
$self->_add_remove($params, 'alias');
# Theoretically you could move a product without ever specifying
# a new assignee or qa_contact, or adding/removing any CCs. So,
@ -2482,13 +2415,14 @@ sub _add_remove {
my ($self, $params, $name) = @_;
my @add = @{ $params->{$name}->{add} || [] };
my @remove = @{ $params->{$name}->{remove} || [] };
$name =~ s/s$// if $name ne 'alias';
$name =~ s/s$//;
my $add_method = "add_$name";
my $remove_method = "remove_$name";
$self->$add_method($_) foreach @add;
$self->$remove_method($_) foreach @remove;
}
sub set_alias { $_[0]->set('alias', $_[1]); }
sub set_assigned_to {
my ($self, $value) = @_;
$self->set('assigned_to', $value);
@ -2905,21 +2839,6 @@ sub remove_cc {
@$cc_users = grep { $_->id != $user->id } @$cc_users;
}
sub add_alias {
my ($self, $alias) = @_;
return if !$alias;
my $aliases = $self->_check_alias($alias);
$alias = $aliases->[0];
my $bug_aliases = $self->alias;
push(@$bug_aliases, $alias) if !grep($_ eq $alias, @$bug_aliases);
}
sub remove_alias {
my ($self, $alias) = @_;
my $bug_aliases = $self->alias;
@$bug_aliases = grep { $_ ne $alias } @$bug_aliases;
}
# $bug->add_comment("comment", {isprivate => 1, work_time => 10.5,
# type => CMT_NORMAL, extra_data => $data});
sub add_comment {
@ -3247,6 +3166,7 @@ sub tags {
# These are accessors that don't need to access the database.
# Keep them in alphabetical order.
sub alias { return $_[0]->{alias} }
sub bug_file_loc { return $_[0]->{bug_file_loc} }
sub bug_id { return $_[0]->{bug_id} }
sub bug_severity { return $_[0]->{bug_severity} }
@ -3356,24 +3276,6 @@ sub actual_time {
return $self->{'actual_time'};
}
sub alias {
my ($self) = @_;
return $self->{'alias'} if exists $self->{'alias'};
return [] if $self->{'error'};
my $dbh = Bugzilla->dbh;
$self->{'alias'} = $dbh->selectcol_arrayref(
q{SELECT alias
FROM bugs_aliases
WHERE bug_id = ?
ORDER BY alias},
undef, $self->bug_id);
$self->{'alias'} = [] if !scalar(@{$self->{'alias'}});
return $self->{'alias'};
}
sub any_flags_requesteeble {
my ($self) = @_;
return $self->{'any_flags_requesteeble'}
@ -3951,11 +3853,6 @@ sub choices {
my @resolutions = grep($_->name, @{ $resolution_field->legal_values });
$choices{'resolution'} = \@resolutions;
foreach my $key (keys %choices) {
my $value = $self->$key;
$choices{$key} = [grep { $_->is_active || $_->name eq $value } @{ $choices{$key} }];
}
$self->{'choices'} = \%choices;
return $self->{'choices'};
}
@ -3970,7 +3867,7 @@ sub bug_alias_to_id {
my $dbh = Bugzilla->dbh;
trick_taint($alias);
return $dbh->selectrow_array(
"SELECT bug_id FROM bugs_aliases WHERE alias = ?", undef, $alias);
"SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
}
#####################################################################
@ -4599,16 +4496,6 @@ __END__
Ensures the accessors for custom fields are always created.
=item C<add_alias($alias)>
Adds an alias to the internal respresentation of the bug. You will need to
call L<update> to make the changes permanent.
=item C<remove_alias($alias)>
Removes an alias from the internal respresentation of the bug. You will need to
call L<update> to make the changes permanent.
=item C<update_user_last_visit($user, $last_visit)>
Creates or updates a L<Bugzilla::BugUserLastVisit> for this bug and the supplied
@ -4776,6 +4663,8 @@ $user, the timestamp given as $last_visit.
=item remove_group
=item set_alias
=item set_dup_id
=item set_target_milestone

View File

@ -9,7 +9,6 @@ package Bugzilla::BugMail;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Error;
use Bugzilla::User;

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Bugzilla;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Bugzilla::Local;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl::Bugzilla);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Debian;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::GitHub;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
@ -22,10 +21,8 @@ sub should_handle {
# GitHub issue URLs have only one form:
# https://github.com/USER_OR_TEAM_OR_ORGANIZATION_NAME/REPOSITORY_NAME/issues/111
# GitHub pull request URLs have only one form:
# https://github.com/USER_OR_TEAM_OR_ORGANIZATION_NAME/REPOSITORY_NAME/pull/111
return (lc($uri->authority) eq 'github.com'
and $uri->path =~ m!^/[^/]+/[^/]+/(?:issues|pull)/\d+$!) ? 1 : 0;
and $uri->path =~ m|^/[^/]+/[^/]+/issues/\d+$|) ? 1 : 0;
}
sub _check_value {

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Google;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::JIRA;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Launchpad;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::MantisBT;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::SourceForge;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
@ -22,18 +21,12 @@ sub should_handle {
# SourceForge tracker URLs have only one form:
# http://sourceforge.net/tracker/?func=detail&aid=111&group_id=111&atid=111
# SourceForge Allura ticket URLs have several forms:
# http://sourceforge.net/p/project/bugs/12345/
# http://sourceforge.net/p/project/feature-requests/12345/
# http://sourceforge.net/p/project/patches/12345/
# http://sourceforge.net/p/project/support-requests/12345/
return (lc($uri->authority) eq 'sourceforge.net'
and (($uri->path eq '/tracker/'
and $uri->query_param('func') eq 'detail'
and $uri->query_param('aid')
and $uri->query_param('group_id')
and $uri->query_param('atid'))
or $uri->path =~ m!^/p/[^/]+/(?:bugs|feature-requests|patches|support-requests)/\d+/?$!)) ? 1 : 0;
and $uri->path =~ m|/tracker/|
and $uri->query_param('func') eq 'detail'
and $uri->query_param('aid')
and $uri->query_param('group_id')
and $uri->query_param('atid')) ? 1 : 0;
}
sub _check_value {
@ -44,11 +37,6 @@ sub _check_value {
# Remove any # part if there is one.
$uri->fragment(undef);
# Make sure the trailing slash is present
my $path = $uri->path;
$path =~ s!/*$!/!;
$uri->path($path);
return $uri;
}

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUrl::Trac;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);

View File

@ -9,7 +9,6 @@ package Bugzilla::BugUserLastVisit;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
@ -39,13 +38,6 @@ sub bug_id { return $_[0]->{bug_id} }
sub user_id { return $_[0]->{user_id} }
sub last_visit_ts { return $_[0]->{last_visit_ts} }
sub user {
my $self = shift;
$self->{user} //= Bugzilla::User->new({ id => $self->user_id, cache => 1 });
return $self->{user};
}
1;
__END__
@ -88,6 +80,4 @@ listed below.
=item C<last_visit_ts>
=item C<user>
=back

View File

@ -9,7 +9,6 @@ package Bugzilla::CGI;
use 5.10.1;
use strict;
use warnings;
use parent qw(CGI);
@ -362,7 +361,6 @@ 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) {
@ -374,7 +372,10 @@ sub param {
if (!scalar(@result)
&& $self->request_method && $self->request_method eq 'POST')
{
@result = $self->url_param(@_);
# Some servers fail to set the QUERY_STRING parameter, which
# causes undef issues
$ENV{'QUERY_STRING'} = '' unless exists $ENV{'QUERY_STRING'};
@result = $self->SUPER::url_param(@_);
}
# Fix UTF-8-ness of input parameters.
@ -399,14 +400,6 @@ sub param {
return $self->SUPER::param(@_);
}
sub url_param {
my $self = shift;
# Some servers fail to set the QUERY_STRING parameter, which
# causes undef issues
$ENV{'QUERY_STRING'} //= '';
return $self->SUPER::url_param(@_);
}
sub _fix_utf8 {
my $input = shift;
# The is_utf8 is here in case CGI gets smart about utf8 someday.
@ -738,8 +731,6 @@ L<CGI|CGI>, L<CGI::Cookie|CGI::Cookie>
=item param
=item url_param
=item header
=back

View File

@ -15,7 +15,6 @@ package Bugzilla::Chart;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Error;
use Bugzilla::Util;
@ -96,9 +95,10 @@ sub init {
if ($self->{'datefrom'} && $self->{'dateto'} &&
$self->{'datefrom'} > $self->{'dateto'})
{
ThrowUserError('misarranged_dates', { 'datefrom' => scalar $cgi->param('datefrom'),
'dateto' => scalar $cgi->param('dateto') });
}
ThrowUserError("misarranged_dates",
{'datefrom' => $cgi->param('datefrom'),
'dateto' => $cgi->param('dateto')});
}
}
# Alter Chart so that the selected series are added to it.

View File

@ -9,7 +9,6 @@ package Bugzilla::Classification;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Field;

View File

@ -9,7 +9,6 @@ package Bugzilla::Comment;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
@ -43,7 +42,6 @@ use constant DB_COLUMNS => qw(
already_wrapped
type
extra_data
is_markdown
);
use constant UPDATE_COLUMNS => qw(
@ -66,7 +64,6 @@ use constant VALIDATORS => {
work_time => \&_check_work_time,
thetext => \&_check_thetext,
isprivate => \&_check_isprivate,
is_markdown => \&Bugzilla::Object::check_boolean,
extra_data => \&_check_extra_data,
type => \&_check_type,
};
@ -179,7 +176,6 @@ sub body { return $_[0]->{'thetext'}; }
sub bug_id { return $_[0]->{'bug_id'}; }
sub creation_ts { return $_[0]->{'bug_when'}; }
sub is_private { return $_[0]->{'isprivate'}; }
sub is_markdown { return $_[0]->{'is_markdown'}; }
sub work_time {
# Work time is returned as a string (see bug 607909)
return 0 if $_[0]->{'work_time'} + 0 == 0;
@ -277,7 +273,6 @@ sub body_full {
sub set_is_private { $_[0]->set('isprivate', $_[1]); }
sub set_type { $_[0]->set('type', $_[1]); }
sub set_extra_data { $_[0]->set('extra_data', $_[1]); }
sub set_is_markdown { $_[0]->set('is_markdown', $_[1]); }
sub add_tag {
my ($self, $tag) = @_;
@ -526,10 +521,6 @@ C<string> Time spent as related to this comment.
C<boolean> Comment is marked as private.
=item C<is_markdown>
C<boolean> Whether this comment needs L<Markdown|Bugzilla::Markdown> rendering to be applied.
=item C<already_wrapped>
If this comment is stored in the database word-wrapped, this will be C<1>.
@ -625,16 +616,6 @@ A string, the full text of the comment as it would be displayed to an end-user.
=cut
=head2 Modifiers
=over
=item C<set_is_markdown>
Sets whether this comment needs L<Markdown|Bugzilla::Markdown> rendering to be applied.
=back
=head1 B<Methods in need of POD>
=over

View File

@ -9,7 +9,6 @@ package Bugzilla::Comment::TagWeights;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);

View File

@ -9,7 +9,6 @@ package Bugzilla::Component;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);

View File

@ -9,19 +9,12 @@ package Bugzilla::Config;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use autodie qw(:default);
use Bugzilla::Constants;
use Bugzilla::Hook;
use Bugzilla::Util qw(trick_taint);
use JSON::XS;
use File::Slurp;
use Data::Dumper;
use File::Temp;
use File::Basename;
# Don't export localvars by default - people should have to explicitly
# ask for it, as a (probably futile) attempt to stop code using it
@ -98,35 +91,8 @@ sub SetParam {
sub update_params {
my ($params) = @_;
my $answer = Bugzilla->installation_answers;
my $datadir = bz_locations()->{'datadir'};
my $param;
# If the old data/params file using Data::Dumper output still exists,
# read it. It will be deleted once the parameters are stored in the new
# data/params.json file.
my $old_file = "$datadir/params";
if (-e $old_file) {
require Safe;
my $s = new Safe;
$s->rdo($old_file);
die "Error reading $old_file: $!" if $!;
die "Error evaluating $old_file: $@" if $@;
# Now read the param back out from the sandbox.
$param = \%{ $s->varglob('param') };
}
else {
# Rename params.js to params.json if checksetup.pl
# was executed with an earlier version of this change
rename "$old_file.js", "$old_file.json"
if -e "$old_file.js" && !-e "$old_file.json";
# Read the new data/params.json file.
$param = read_param_file();
}
my $param = read_param_file();
my %new_params;
# If we didn't return any param values, then this is a new installation.
@ -185,19 +151,16 @@ sub update_params {
}
# Old mail_delivery_method choices contained no uppercase characters
my $mta = $param->{'mail_delivery_method'};
if ($mta) {
if ($mta !~ /[A-Z]/) {
my %translation = (
'sendmail' => 'Sendmail',
'smtp' => 'SMTP',
'qmail' => 'Qmail',
'testfile' => 'Test',
'none' => 'None');
$param->{'mail_delivery_method'} = $translation{$mta};
}
# This will force the parameter to be reset to its default value.
delete $param->{'mail_delivery_method'} if $param->{'mail_delivery_method'} eq 'Qmail';
if (exists $param->{'mail_delivery_method'}
&& $param->{'mail_delivery_method'} !~ /[A-Z]/) {
my $method = $param->{'mail_delivery_method'};
my %translation = (
'sendmail' => 'Sendmail',
'smtp' => 'SMTP',
'qmail' => 'Qmail',
'testfile' => 'Test',
'none' => 'None');
$param->{'mail_delivery_method'} = $translation{$method};
}
# Convert the old "ssl" parameter to the new "ssl_redirect" parameter.
@ -247,6 +210,7 @@ sub update_params {
}
# Write any old parameters to old-params.txt
my $datadir = bz_locations()->{'datadir'};
my $old_param_file = "$datadir/old-params.txt";
if (scalar(keys %oldparams)) {
my $op_file = new IO::File($old_param_file, '>>', 0600)
@ -256,9 +220,12 @@ sub update_params {
" and so have been\nmoved from your parameters file into",
" $old_param_file:\n";
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
my $comma = "";
foreach my $item (keys %oldparams) {
print $op_file "\n\n$item:\n" . $oldparams{$item} . "\n";
print $op_file "\n\n$item:\n" . Data::Dumper->Dump([$oldparams{$item}]) . "\n";
print "${comma}$item";
$comma = ", ";
}
@ -289,11 +256,6 @@ sub update_params {
write_params($param);
if (-e $old_file) {
unlink $old_file;
say "$old_file has been converted into $old_file.json, using the JSON format.";
}
# Return deleted params and values so that checksetup.pl has a chance
# to convert old params to new data.
return %oldparams;
@ -302,10 +264,22 @@ sub update_params {
sub write_params {
my ($param_data) = @_;
$param_data ||= Bugzilla->params;
my $param_file = bz_locations()->{'datadir'} . '/params.json';
my $json_data = JSON::XS->new->canonical->pretty->encode($param_data);
write_file($param_file, { binmode => ':utf8', atomic => 1 }, \$json_data);
my $datadir = bz_locations()->{'datadir'};
my $param_file = "$datadir/params";
local $Data::Dumper::Sortkeys = 1;
my ($fh, $tmpname) = File::Temp::tempfile('params.XXXXX',
DIR => $datadir );
print $fh (Data::Dumper->Dump([$param_data], ['*param']))
|| die "Can't write param file: $!";
close $fh;
rename $tmpname, $param_file
or die "Can't rename $tmpname to $param_file: $!";
# It's not common to edit parameters and loading
# Bugzilla::Install::Filesystem is slow.
@ -319,23 +293,21 @@ sub write_params {
sub read_param_file {
my %params;
my $file = bz_locations()->{'datadir'} . '/params.json';
my $datadir = bz_locations()->{'datadir'};
if (-e "$datadir/params") {
# Note that checksetup.pl sets file permissions on '$datadir/params'
if (-e $file) {
my $data;
read_file($file, binmode => ':utf8', buf_ref => \$data);
# Using Safe mode is _not_ a guarantee of safety if someone does
# manage to write to the file. However, it won't hurt...
# See bug 165144 for not needing to eval this at all
my $s = new Safe;
# If params.json has been manually edited and e.g. some quotes are
# missing, we don't want JSON::XS to leak the content of the file
# to all users in its error message, so we have to eval'uate it.
%params = eval { %{JSON::XS->new->decode($data)} };
if ($@) {
my $error_msg = (basename($0) eq 'checksetup.pl') ?
$@ : 'run checksetup.pl to see the details.';
die "Error parsing $file: $error_msg";
}
# JSON::XS doesn't detaint data for us.
trick_taint($params{$_}) foreach keys %params;
$s->rdo("$datadir/params");
die "Error reading $datadir/params: $!" if $!;
die "Error evaluating $datadir/params: $@" if $@;
# Now read the param back out from the sandbox
%params = %{$s->varglob('param')};
}
elsif ($ENV{'SERVER_SOFTWARE'}) {
# We're in a CGI, but the params file doesn't exist. We can't
@ -345,7 +317,7 @@ sub read_param_file {
# so that the user sees the error.
require CGI::Carp;
CGI::Carp->import('fatalsToBrowser');
die "The $file file does not exist."
die "The $datadir/params file does not exist."
. ' You probably need to run checksetup.pl.',
}
return \%params;
@ -401,7 +373,7 @@ specified.
Description: Writes the parameters to disk.
Params: C<$params> (optional) - A hashref to write to the disk
instead of C<Bugzilla-E<gt>params>. Used only by
instead of C<Bugzilla->params>. Used only by
C<update_params>.
Returns: nothing
@ -409,12 +381,12 @@ Returns: nothing
=item C<read_param_file()>
Description: Most callers should never need this. This is used
by C<Bugzilla-E<gt>params> to directly read C<$datadir/params.json>
and load it into memory. Use C<Bugzilla-E<gt>params> instead.
by C<Bugzilla->params> to directly read C<$datadir/params>
and load it into memory. Use C<Bugzilla->params> instead.
Params: none
Returns: A hashref containing the current params in C<$datadir/params.json>.
Returns: A hashref containing the current params in C<$datadir/params>.
=item C<param_panels()>

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Admin;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Advanced;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Attachment;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
@ -37,14 +36,6 @@ sub get_param_list {
default => 0
},
{
name => 'xsendfile_header',
type => 's',
choices => ['off', 'X-Sendfile', 'X-Accel-Redirect', 'X-LIGHTTPD-send-file'],
default => 'off',
checker => \&check_multi
},
{
name => 'maxattachmentsize',
type => 't',

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Auth;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
@ -114,14 +113,7 @@ sub get_param_list {
'letters_numbers_specialchars' ],
default => 'no_constraints',
checker => \&check_multi
},
{
name => 'password_check_on_login',
type => 'b',
default => '1'
},
);
} );
return @param_list;
}

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::BugChange;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
use Bugzilla::Status;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::BugFields;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
use Bugzilla::Field;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Common;
use 5.10.1;
use strict;
use warnings;
use Email::Address;
use Socket;
@ -29,7 +28,7 @@ use parent qw(Exporter);
check_mail_delivery_method check_notification check_utf8
check_bug_status check_smtp_auth check_theschwartz_available
check_maxattachmentsize check_email check_smtp_ssl
check_comment_taggers_group check_smtp_server
check_comment_taggers_group
);
# Checking functions for the various values
@ -342,33 +341,6 @@ 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)";
}
}
trick_taint($host);
# Let's first try to connect using SSL. If this fails, we fall back to
# an unencrypted connection.
foreach my $method (['Net::SMTP::SSL', 465], ['Net::SMTP', 25]) {
my ($class, $default_port) = @$method;
next if $class eq 'Net::SMTP::SSL' && !Bugzilla->feature('smtp_ssl');
eval "require $class";
my $smtp = $class->new($host, Port => $port || $default_port, Timeout => 5);
if ($smtp) {
# The connection works!
$smtp->quit;
return '';
}
}
return "Cannot connect to $host" . ($port ? " using port $port" : "");
}
sub check_smtp_auth {
my $username = shift;
if ($username and !Bugzilla->feature('smtp_auth')) {
@ -525,8 +497,6 @@ valid group is provided.
=item check_shadowdb
=item check_smtp_server
=item check_smtp_auth
=item check_url

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Core;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::DependencyGraph;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
@ -21,7 +20,7 @@ sub get_param_list {
{
name => 'webdotbase',
type => 't',
default => '',
default => 'http://www.research.att.com/~north/cgi-bin/webdot.cgi/%urlbase%',
checker => \&check_webdotbase
},

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::General;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::GroupSecurity;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
use Bugzilla::Group;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::LDAP;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,9 +9,15 @@ package Bugzilla::Config::MTA;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;
# Return::Value 1.666002 pollutes the error log with warnings about this
# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send
# to disable these warnings.
BEGIN {
$Return::Value::NO_CLUCK = 1;
}
use Email::Send;
our $sortkey = 1200;
@ -21,7 +27,9 @@ sub get_param_list {
{
name => 'mail_delivery_method',
type => 's',
choices => ['Sendmail', 'SMTP', 'Test', 'None'],
# Bugzilla is not ready yet to send mails to newsgroups, and 'IO'
# is of no use for now as we already have our own 'Test' mode.
choices => [grep {$_ ne 'NNTP' && $_ ne 'IO'} Email::Send->new()->all_mailers(), 'None'],
default => 'Sendmail',
checker => \&check_mail_delivery_method
},
@ -42,8 +50,7 @@ sub get_param_list {
{
name => 'smtpserver',
type => 't',
default => 'localhost',
checker => \&check_smtp_server
default => 'localhost'
},
{
name => 'smtp_username',

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Memcached;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -0,0 +1,52 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
package Bugzilla::Config::PatchViewer;
use 5.10.1;
use strict;
use Bugzilla::Config::Common;
our $sortkey = 1300;
sub get_param_list {
my $class = shift;
my @param_list = (
{
name => 'cvsroot',
type => 't',
default => '',
},
{
name => 'cvsroot_get',
type => 't',
default => '',
},
{
name => 'bonsai_url',
type => 't',
default => ''
},
{
name => 'lxr_url',
type => 't',
default => ''
},
{
name => 'lxr_root',
type => 't',
default => '',
} );
return @param_list;
}
1;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::Query;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::RADIUS;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::ShadowDB;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Config::UserMatch;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Config::Common;

View File

@ -9,7 +9,6 @@ package Bugzilla::Constants;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
@ -26,8 +25,6 @@ use Memoize;
bz_locations
CONCATENATE_ASSETS
IS_NULL
NOT_NULL
@ -193,14 +190,6 @@ use Memoize;
AUDIT_REMOVE
MOST_FREQUENT_THRESHOLD
MARKDOWN_TAB_WIDTH
EMAIL_LIMIT_PER_MINUTE
EMAIL_LIMIT_PER_HOUR
EMAIL_LIMIT_EXCEPTION
JOB_QUEUE_VIEW_MAX_JOBS
);
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
@ -208,7 +197,7 @@ use Memoize;
# CONSTANTS
#
# Bugzilla version
use constant BUGZILLA_VERSION => "5.1";
use constant BUGZILLA_VERSION => "4.5.4+";
# A base link to the current REST Documentation. We place it here
# as it will need to be updated to whatever the current release is.
@ -218,11 +207,6 @@ use constant REST_DOC => "http://www.bugzilla.org/docs/tip/en/html/api/";
use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml';
use constant LOCAL_FILE => 'bugzilla-update.xml'; # Relative to datadir.
# When true CSS and JavaScript assets will be concatanted and minified at
# run-time, to reduce the number of requests required to render a page.
# Setting this to a false value can help debugging.
use constant CONCATENATE_ASSETS => 1;
# These are unique values that are unlikely to match a string or a number,
# to be used in criteria for match() functions and other things. They start
# and end with spaces because most Bugzilla stuff has trim() called on it,
@ -643,22 +627,6 @@ use constant AUDIT_REMOVE => '__remove__';
# on the "Most frequently reported bugs" page.
use constant MOST_FREQUENT_THRESHOLD => 2;
# The number of spaces used to represent each tab character
# by Markdown engine
use constant MARKDOWN_TAB_WIDTH => 2;
# The maximum number of emails per minute and hour a recipient can receive.
# Email will be queued/backlogged to avoid exceeeding these limits.
# Setting a limit to 0 will disable this feature.
use constant EMAIL_LIMIT_PER_MINUTE => 1000;
use constant EMAIL_LIMIT_PER_HOUR => 2500;
# Don't change this exception message.
use constant EMAIL_LIMIT_EXCEPTION => "email_limit_exceeded\n";
# The maximum number of jobs to show when viewing the job queue
# (view_job_queue.cgi).
use constant JOB_QUEUE_VIEW_MAX_JOBS => 500;
sub bz_locations {
# Force memoize() to re-compute data per project, to avoid
# sharing the same data across different installations.

View File

@ -9,7 +9,6 @@ package Bugzilla::DB;
use 5.10.1;
use strict;
use warnings;
use DBI;
@ -17,7 +16,6 @@ use DBI;
use parent -norequire, qw(DBI::db);
use Bugzilla::Constants;
use Bugzilla::Mailer;
use Bugzilla::Install::Requirements;
use Bugzilla::Install::Util qw(install_string);
use Bugzilla::Install::Localconfig;
@ -115,6 +113,7 @@ sub connect_shadow {
}
sub connect_main {
my $lc = Bugzilla->localconfig;
return _connect(Bugzilla->localconfig);
}
@ -580,11 +579,8 @@ 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, $trimmed_def,
$table, $name, $new_def,
defined $init_value ? $self->quote($init_value) : undef);
print get_text('install_column_add',
{ column => $name, table => $table }) . "\n"
@ -598,14 +594,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;
}
@ -1213,13 +1209,12 @@ sub bz_start_transaction {
sub bz_commit_transaction {
my ($self) = @_;
if ($self->{private_bz_transaction_count} > 1) {
$self->{private_bz_transaction_count}--;
} elsif ($self->bz_in_transaction) {
$self->commit();
$self->{private_bz_transaction_count} = 0;
Bugzilla::Mailer->send_staged_mail();
} else {
ThrowCodeError('not_in_transaction');
}
@ -2320,11 +2315,7 @@ values to.
=item C<$name> - the name of the new column
=item C<$definition> - A hashref abstract column definition for the new column.
Note, if a C<REFERENCES> definition is included to create a foreign key
relationship, it will be created later instead of when the column is added.
Normally foreign keys are added by C<checksetup.pl> at the end all at the same
time.
=item C<\%definition> - Abstract column definition for the new column
=item C<$init_value> (optional) - An initial value to set the column
to. Required if your column is NOT NULL and has no DEFAULT set.

View File

@ -23,7 +23,6 @@ package Bugzilla::DB::Mysql;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB);
@ -86,18 +85,17 @@ sub new {
$self->{private_bz_dsn} = $dsn;
bless ($self, $class);
# Check for MySQL modes.
# Bug 321645 - disable MySQL strict mode, if set
my ($var, $sql_mode) = $self->selectrow_array(
"SHOW VARIABLES LIKE 'sql\\_mode'");
# Disable ANSI and strict modes, else Bugzilla will crash.
if ($sql_mode) {
# STRICT_TRANS_TABLE or STRICT_ALL_TABLES enable MySQL strict mode,
# causing bug 321645. TRADITIONAL sets these modes (among others) as
# well, so it has to be stipped as well
my $new_sql_mode =
join(",", grep {$_ !~ /^(?:ANSI|STRICT_(?:TRANS|ALL)_TABLES|TRADITIONAL)$/}
join(",", grep {$_ !~ /^STRICT_(?:TRANS|ALL)_TABLES|TRADITIONAL$/}
split(/,/, $sql_mode));
if ($sql_mode ne $new_sql_mode) {
@ -294,6 +292,7 @@ sub _bz_get_initial_schema {
sub bz_check_server_version {
my $self = shift;
my $lc = Bugzilla->localconfig;
if (lc(Bugzilla->localconfig->{db_name}) eq 'mysql') {
die "It is not safe to run Bugzilla inside a database named 'mysql'.\n"
. " Please pick a different value for \$db_name in localconfig.\n";

View File

@ -23,7 +23,6 @@ package Bugzilla::DB::Oracle;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB);
@ -722,7 +721,6 @@ package Bugzilla::DB::Oracle::st;
use 5.10.1;
use strict;
use warnings;
use parent -norequire, qw(DBI::st);

View File

@ -23,7 +23,6 @@ package Bugzilla::DB::Pg;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Error;
use Bugzilla::Version;
@ -231,9 +230,6 @@ sub bz_setup_database {
my $self = shift;
$self->SUPER::bz_setup_database(@_);
my ($has_plpgsql) = $self->selectrow_array("SELECT COUNT(*) FROM pg_language WHERE lanname = 'plpgsql'");
$self->do('CREATE LANGUAGE plpgsql') unless $has_plpgsql;
# Custom Functions
# -Copyright © 2013 Joshua D. Burns (JDBurnZ) and Message In Action LLC

View File

@ -17,7 +17,6 @@ package Bugzilla::DB::Schema;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Error;
use Bugzilla::Hook;
@ -278,8 +277,11 @@ use constant ABSTRACT_SCHEMA => {
remaining_time => {TYPE => 'decimal(7,2)',
NOTNULL => 1, DEFAULT => '0'},
deadline => {TYPE => 'DATETIME'},
alias => {TYPE => 'varchar(20)'},
],
INDEXES => [
bugs_alias_idx => {FIELDS => ['alias'],
TYPE => 'UNIQUE'},
bugs_assigned_to_idx => ['assigned_to'],
bugs_creation_ts_idx => ['creation_ts'],
bugs_delta_ts_idx => ['delta_ts'],
@ -356,21 +358,6 @@ use constant ABSTRACT_SCHEMA => {
],
},
bugs_aliases => {
FIELDS => [
alias => {TYPE => 'varchar(40)', NOTNULL => 1},
bug_id => {TYPE => 'INT3',
REFERENCES => {TABLE => 'bugs',
COLUMN => 'bug_id',
DELETE => 'CASCADE'}},
],
INDEXES => [
bugs_aliases_bug_id_idx => ['bug_id'],
bugs_aliases_alias_idx => {FIELDS => ['alias'],
TYPE => 'UNIQUE'},
],
},
cc => {
FIELDS => [
bug_id => {TYPE => 'INT3', NOTNULL => 1,
@ -410,8 +397,7 @@ use constant ABSTRACT_SCHEMA => {
DEFAULT => 'FALSE'},
type => {TYPE => 'INT2', NOTNULL => 1,
DEFAULT => '0'},
extra_data => {TYPE => 'varchar(255)'},
is_markdown => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}
extra_data => {TYPE => 'varchar(255)'}
],
INDEXES => [
longdescs_bug_id_idx => [qw(bug_id work_time)],
@ -1191,7 +1177,7 @@ use constant ABSTRACT_SCHEMA => {
issuedate => {TYPE => 'DATETIME', NOTNULL => 1} ,
token => {TYPE => 'varchar(16)', NOTNULL => 1,
PRIMARYKEY => 1},
tokentype => {TYPE => 'varchar(16)', NOTNULL => 1} ,
tokentype => {TYPE => 'varchar(8)', NOTNULL => 1} ,
eventdata => {TYPE => 'TINYTEXT'},
],
INDEXES => [
@ -1630,28 +1616,6 @@ use constant ABSTRACT_SCHEMA => {
],
},
# BUGMAIL
# -------
mail_staging => {
FIELDS => [
id => {TYPE => 'INTSERIAL', PRIMARYKEY => 1, NOTNULL => 1},
message => {TYPE => 'LONGBLOB', NOTNULL => 1},
],
},
email_rates => {
FIELDS => [
id => {TYPE => 'INTSERIAL', NOTNULL => 1,
PRIMARYKEY => 1},
recipient => {TYPE => 'varchar(255)', NOTNULL => 1},
message_ts => {TYPE => 'DATETIME', NOTNULL => 1},
],
INDEXES => [
email_rates_idx => [qw(recipient message_ts)],
],
},
# THESCHWARTZ TABLES
# ------------------
# Note: In the standard TheSchwartz schema, most integers are unsigned,
@ -1769,26 +1733,6 @@ use constant ABSTRACT_SCHEMA => {
bug_user_last_visit_last_visit_ts_idx => ['last_visit_ts'],
],
},
user_api_keys => {
FIELDS => [
id => {TYPE => 'INTSERIAL', NOTNULL => 1,
PRIMARYKEY => 1},
user_id => {TYPE => 'INT3', NOTNULL => 1,
REFERENCES => {TABLE => 'profiles',
COLUMN => 'userid',
DELETE => 'CASCADE'}},
api_key => {TYPE => 'VARCHAR(40)', NOTNULL => 1},
description => {TYPE => 'VARCHAR(255)'},
revoked => {TYPE => 'BOOLEAN', NOTNULL => 1,
DEFAULT => 'FALSE'},
last_used => {TYPE => 'DATETIME'},
],
INDEXES => [
user_api_keys_api_key_idx => {FIELDS => ['api_key'], TYPE => 'UNIQUE'},
user_api_keys_user_id_idx => ['user_id'],
],
},
};
# Foreign Keys are added in Bugzilla::DB::bz_add_field_tables

View File

@ -15,7 +15,6 @@ package Bugzilla::DB::Schema::Mysql;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Error;

View File

@ -15,7 +15,6 @@ package Bugzilla::DB::Schema::Oracle;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);
use Carp qw(confess);

View File

@ -15,7 +15,6 @@ package Bugzilla::DB::Schema::Pg;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);
use Storable qw(dclone);

View File

@ -9,7 +9,6 @@ package Bugzilla::DB::Schema::Sqlite;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);

View File

@ -9,7 +9,6 @@ package Bugzilla::DB::Sqlite;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB);

View File

@ -9,7 +9,6 @@ package Bugzilla::Error;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);

View File

@ -9,7 +9,6 @@ package Bugzilla::Extension;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Error;

View File

@ -59,7 +59,6 @@ package Bugzilla::Field;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter Bugzilla::Object);
@Bugzilla::Field::EXPORT = qw(check_field get_field_id get_legal_field_values);

View File

@ -9,7 +9,6 @@ package Bugzilla::Field::Choice;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);

View File

@ -9,7 +9,6 @@ package Bugzilla::Field::ChoiceInterface;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Error;

View File

@ -9,7 +9,6 @@ package Bugzilla::Flag;
use 5.10.1;
use strict;
use warnings;
=head1 NAME
@ -454,15 +453,14 @@ sub create {
sub update {
my $self = shift;
my $dbh = Bugzilla->dbh;
my $timestamp = shift || $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
my $timestamp = shift || $dbh->selectrow_array('SELECT NOW()');
my $changes = $self->SUPER::update(@_);
if (scalar(keys %$changes)) {
$dbh->do('UPDATE flags SET modification_date = ? WHERE id = ?',
undef, ($timestamp, $self->id));
$self->{'modification_date'} =
format_time($timestamp, '%Y.%m.%d %T', Bugzilla->local_timezone);
$self->{'modification_date'} = format_time($timestamp, '%Y.%m.%d %T');
Bugzilla->memcached->clear({ table => 'flags', id => $self->id });
}
return $changes;
@ -933,117 +931,6 @@ sub extract_flags_from_cgi {
=over
=item C<multi_extract_flags_from_cgi($bug, $hr_vars)>
Checks whether or not there are new flags to create and returns an
array of hashes. This array is then passed to Flag::create(). This differs
from the previous sub-routine as it is called for changing multiple bugs
=back
=cut
sub multi_extract_flags_from_cgi {
my ($class, $bug, $vars, $skip) = @_;
my $cgi = Bugzilla->cgi;
my $match_status = Bugzilla::User::match_field({
'^requestee(_type)?-(\d+)$' => { 'type' => 'multi' },
}, undef, $skip);
$vars->{'match_field'} = 'requestee';
if ($match_status == USER_MATCH_FAILED) {
$vars->{'message'} = 'user_match_failed';
}
elsif ($match_status == USER_MATCH_MULTIPLE) {
$vars->{'message'} = 'user_match_multiple';
}
# Extract a list of flag type IDs from field names.
my @flagtype_ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param());
my (@new_flags, @flags);
# Get a list of active flag types available for this product/component.
my $flag_types = Bugzilla::FlagType::match(
{ 'product_id' => $bug->{'product_id'},
'component_id' => $bug->{'component_id'},
'is_active' => 1 });
foreach my $flagtype_id (@flagtype_ids) {
# Checks if there are unexpected flags for the product/component.
if (!scalar(grep { $_->id == $flagtype_id } @$flag_types)) {
$vars->{'message'} = 'unexpected_flag_types';
last;
}
}
foreach my $flag_type (@$flag_types) {
my $type_id = $flag_type->id;
# Bug flags are only valid for bugs
next unless ($flag_type->target_type eq 'bug');
# We are only interested in flags the user tries to create.
next unless scalar(grep { $_ == $type_id } @flagtype_ids);
# Get the flags of this type already set for this bug.
my $current_flags = $class->match(
{ 'type_id' => $type_id,
'target_type' => 'bug',
'bug_id' => $bug->bug_id });
# We will update existing flags (instead of creating new ones)
# if the flag exists and the user has not chosen the 'always add'
# option
my $update = scalar(@$current_flags) && ! $cgi->param("flags_add-$type_id");
my $status = $cgi->param("flag_type-$type_id");
trick_taint($status);
my @logins = $cgi->param("requestee_type-$type_id");
if ($status eq "?" && scalar(@logins)) {
foreach my $login (@logins) {
if ($update) {
foreach my $current_flag (@$current_flags) {
push (@flags, { id => $current_flag->id,
status => $status,
requestee => $login,
skip_roe => $skip });
}
}
else {
push (@new_flags, { type_id => $type_id,
status => $status,
requestee => $login,
skip_roe => $skip });
}
last unless $flag_type->is_multiplicable;
}
}
else {
if ($update) {
foreach my $current_flag (@$current_flags) {
push (@flags, { id => $current_flag->id,
status => $status });
}
}
else {
push (@new_flags, { type_id => $type_id,
status => $status });
}
}
}
# Return the list of flags to update and/or to create.
return (\@flags, \@new_flags);
}
=pod
=over
=item C<notify($flag, $old_flag, $object, $timestamp)>
Sends an email notification about a flag being created, fulfilled
@ -1124,32 +1011,18 @@ sub notify {
$default_lang = Bugzilla::User->new()->setting('lang');
}
# Get comments on the bug
my $all_comments = $bug->comments({ after => $bug->lastdiffed });
@$all_comments = grep { $_->type || $_->body =~ /\S/ } @$all_comments;
# Get public only comments
my $public_comments = [ grep { !$_->is_private } @$all_comments ];
foreach my $to (keys %recipients) {
# Add threadingmarker to allow flag notification emails to be the
# threaded similar to normal bug change emails.
my $thread_user_id = $recipients{$to} ? $recipients{$to}->id : 0;
# We only want to show private comments to users in the is_insider group
my $comments = $recipients{$to} && $recipients{$to}->is_insider
? $all_comments : $public_comments;
my $vars = {
flag => $flag,
old_flag => $old_flag,
to => $to,
date => $timestamp,
bug => $bug,
attachment => $attachment,
threadingmarker => build_thread_marker($bug->id, $thread_user_id),
new_comments => $comments,
};
my $vars = { 'flag' => $flag,
'old_flag' => $old_flag,
'to' => $to,
'date' => $timestamp,
'bug' => $bug,
'attachment' => $attachment,
'threadingmarker' => build_thread_marker($bug->id, $thread_user_id) };
my $lang = $recipients{$to} ?
$recipients{$to}->setting('lang') : $default_lang;

View File

@ -9,7 +9,6 @@ package Bugzilla::FlagType;
use 5.10.1;
use strict;
use warnings;
=head1 NAME
@ -41,7 +40,6 @@ use Bugzilla::Util;
use Bugzilla::Group;
use Email::Address;
use List::MoreUtils qw(uniq);
use parent qw(Bugzilla::Object);
@ -380,6 +378,8 @@ 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;
@ -405,22 +405,6 @@ 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;

View File

@ -9,7 +9,6 @@ package Bugzilla::Group;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
@ -56,10 +55,8 @@ use constant UPDATE_COLUMNS => qw(
);
# Parameters that are lists of groups.
use constant GROUP_PARAMS => qw(
chartgroup comment_taggers_group debug_group insidergroup
querysharegroup timetrackinggroup
);
use constant GROUP_PARAMS => qw(chartgroup insidergroup timetrackinggroup
querysharegroup);
###############################
#### Accessors ######

View File

@ -9,7 +9,6 @@ package Bugzilla::Hook;
use 5.10.1;
use strict;
use warnings;
sub process {
my ($name, $args) = @_;
@ -1033,6 +1032,9 @@ Params:
=item C<email> - The C<Email::MIME> object that's about to be sent.
=item C<mailer_args> - An arrayref that's passed as C<mailer_args> to
L<Email::Send/new>.
=back
=head2 object_before_create
@ -1704,26 +1706,6 @@ The current JSONRPC, XMLRPC, or REST object.
=back
=head2 webservice_status_code_map
This hook allows an extension to change the status codes returned by
specific webservice errors. The valid internal error codes that Bugzilla
generates, and the status codes they map to by default, are defined in the
C<WS_ERROR_CODE> constant in C<Bugzilla::WebService::Constants>. When
remapping an error, you may wish to use an existing status code constant.
Such constants are also in C<Bugzilla::WebService::Constants> and start
with C<STATUS_*> such as C<STATUS_BAD_REQUEST>.
Params:
=over
=item C<status_code_map>
A hash reference containing the current status code mapping.
=back
=head1 SEE ALSO
L<Bugzilla::Extension>

View File

@ -17,7 +17,6 @@ package Bugzilla::Install;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Component;
use Bugzilla::Config qw(:admin);
@ -90,8 +89,6 @@ sub SETTINGS {
bugmail_new_prefix => { options => ['on', 'off'], default => 'on' },
# 2013-07-26 joshi_sunil@in.com -- Bug 669535
possible_duplicates => { options => ['on', 'off'], default => 'on' },
# 2014-05-24 koosha.khajeh@gmail.com -- Bug 1014164
use_markdown => { options => ['on', 'off'], default => 'on' },
}
};
@ -135,13 +132,11 @@ use constant SYSTEM_GROUPS => (
},
{
name => 'bz_canusewhineatothers',
description => 'Can configure queries and schedules for periodic'
. ' reports to be run and sent via email to other users and groups',
description => 'Can configure whine reports for other users',
},
{
name => 'bz_canusewhines',
description => 'Can configure queries and schedules for periodic'
. ' reports to be run and sent via email to themselves',
description => 'User can configure whine reports for self',
# inherited_by means that users in the groups listed below are
# automatically members of bz_canusewhines.
inherited_by => ['editbugs', 'bz_canusewhineatothers'],
@ -219,8 +214,8 @@ sub update_system_groups {
# Create most of the system groups
foreach my $definition (SYSTEM_GROUPS) {
my $group = new Bugzilla::Group({ name => $definition->{name} });
if (!$group) {
my $exists = new Bugzilla::Group({ name => $definition->{name} });
if (!$exists) {
$definition->{isbuggroup} = 0;
$definition->{silently} = !$editbugs_exists;
my $inherited_by = delete $definition->{inherited_by};
@ -236,10 +231,6 @@ sub update_system_groups {
}
}
}
elsif ($group->description ne $definition->{description}) {
$group->set_description($definition->{description});
$group->update();
}
}
$dbh->bz_commit_transaction();

View File

@ -9,7 +9,6 @@ package Bugzilla::Install::CPAN;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
our @EXPORT = qw(

View File

@ -12,7 +12,6 @@ package Bugzilla::Install::DB;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Hook;
@ -273,6 +272,10 @@ sub update_table_definitions {
$dbh->bz_add_column('attachments', 'isprivate',
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
$dbh->bz_add_column("bugs", "alias", {TYPE => "varchar(20)"});
$dbh->bz_add_index('bugs', 'bugs_alias_idx',
{TYPE => 'UNIQUE', FIELDS => [qw(alias)]});
_move_quips_into_db();
$dbh->bz_drop_column("namedqueries", "watchfordiffs");
@ -716,20 +719,6 @@ sub update_table_definitions {
'bug_user_last_visit_last_visit_ts_idx',
['last_visit_ts']);
# 2014-07-14 sgreen@redhat.com - Bug 726696
$dbh->bz_alter_column('tokens', 'tokentype',
{TYPE => 'varchar(16)', NOTNULL => 1});
# 2014-07-27 LpSolit@gmail.com - Bug 1044561
_fix_user_api_keys_indexes();
# 2014-08-11 sgreen@redhat.com - Bug 1012506
_update_alias();
# 2014-08-14 koosha.khajeh@gmail.com - Bug 330707
$dbh->bz_add_column('longdescs', 'is_markdown',
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
@ -2561,7 +2550,7 @@ sub _fix_whine_queries_title_and_op_sys_value {
undef, "Other", "other");
if (Bugzilla->params->{'defaultopsys'} eq 'other') {
# We can't actually fix the param here, because WriteParams() will
# make $datadir/params.json unwriteable to the webservergroup.
# make $datadir/params unwriteable to the webservergroup.
# It's too much of an ugly hack to copy the permission-fixing code
# down to here. (It would create more potential future bugs than
# it would solve problems.)
@ -3888,33 +3877,6 @@ sub _fix_components_primary_key {
}
}
sub _fix_user_api_keys_indexes {
my $dbh = Bugzilla->dbh;
if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_key')) {
$dbh->bz_drop_index('user_api_keys', 'user_api_keys_key');
$dbh->bz_add_index('user_api_keys', 'user_api_keys_api_key_idx',
{ FIELDS => ['api_key'], TYPE => 'UNIQUE' });
}
if ($dbh->bz_index_info('user_api_keys', 'user_api_keys_user_id')) {
$dbh->bz_drop_index('user_api_keys', 'user_api_keys_user_id');
$dbh->bz_add_index('user_api_keys', 'user_api_keys_user_id_idx', ['user_id']);
}
}
sub _update_alias {
my $dbh = Bugzilla->dbh;
return unless $dbh->bz_column_info('bugs', 'alias');
# We need to move the aliases from the bugs table to the bugs_aliases table
$dbh->do(q{
INSERT INTO bugs_aliases (bug_id, alias)
SELECT bug_id, alias FROM bugs WHERE alias IS NOT NULL
});
$dbh->bz_drop_column('bugs', 'alias');
}
1;
__END__

View File

@ -17,7 +17,6 @@ package Bugzilla::Install::Filesystem;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Error;
@ -31,7 +30,6 @@ use File::Path;
use File::Basename;
use File::Copy qw(move);
use File::Spec;
use File::Slurp;
use IO::File;
use POSIX ();
@ -167,13 +165,12 @@ sub FILESYSTEM {
'contrib/README' => { perms => OWNER_WRITE },
'contrib/*/README' => { perms => OWNER_WRITE },
'contrib/Bugzilla.pm' => { perms => OWNER_WRITE },
'contrib/replyrc' => { perms => OWNER_WRITE },
'docs/bugzilla.ent' => { perms => OWNER_WRITE },
'docs/makedocs.pl' => { perms => OWNER_EXECUTE },
'docs/style.css' => { perms => WS_SERVE },
'docs/*/rel_notes.txt' => { perms => WS_SERVE },
'docs/*/README.docs' => { perms => OWNER_WRITE },
"$datadir/params.json" => { perms => CGI_WRITE },
"$datadir/params" => { perms => CGI_WRITE },
"$datadir/old-params.txt" => { perms => OWNER_WRITE },
"$extensionsdir/create.pl" => { perms => OWNER_EXECUTE },
"$extensionsdir/*/*.pl" => { perms => WS_EXECUTE },
@ -369,7 +366,7 @@ EOT
"$assetsdir/.htaccess" => { perms => WS_SERVE, contents => <<EOT
# Allow access to .css files
<FilesMatch \\.(css|js)\$>
<FilesMatch \\.css\$>
Allow from all
</FilesMatch>
@ -412,7 +409,6 @@ sub update_filesystem {
my $datadir = bz_locations->{'datadir'};
my $graphsdir = bz_locations->{'graphsdir'};
my $assetsdir = bz_locations->{'assetsdir'};
# If the graphs/ directory doesn't exist, we're upgrading from
# a version old enough that we need to update the $datadir/mining
# format.
@ -453,13 +449,6 @@ sub update_filesystem {
_rename_file($oldparamsfile, "$datadir/$oldparamsfile");
}
# Remove old assets htaccess file to force recreation with correct values.
if (-e "$assetsdir/.htaccess") {
if (read_file("$assetsdir/.htaccess") =~ /<FilesMatch \\\.css\$>/) {
unlink("$assetsdir/.htaccess");
}
}
_create_files(%files);
if ($params->{index_html}) {
_create_files(%{$fs->{index_html}});
@ -503,7 +492,7 @@ EOT
_remove_empty_css_files();
_convert_single_file_skins();
_remove_dynamic_assets();
_remove_dynamic_css_files();
}
sub _remove_empty_css_files {
@ -548,14 +537,10 @@ sub _convert_single_file_skins {
}
}
# delete all automatically generated css/js files to force recreation at the
# next request.
sub _remove_dynamic_assets {
my @files = (
glob(bz_locations()->{assetsdir} . '/*.css'),
glob(bz_locations()->{assetsdir} . '/*.js'),
);
foreach my $file (@files) {
# delete all automatically generated css files to force recreation at the next
# request.
sub _remove_dynamic_css_files {
foreach my $file (glob(bz_locations()->{assetsdir} . '/*.css')) {
unlink($file);
}

View File

@ -17,7 +17,6 @@ package Bugzilla::Install::Localconfig;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(bin_loc install_string);
@ -100,6 +99,10 @@ use constant LOCALCONFIG_VARS => (
name => 'index_html',
default => 0,
},
{
name => 'cvsbin',
default => sub { bin_loc('cvs') },
},
{
name => 'interdiffbin',
default => sub { bin_loc('interdiff') },

View File

@ -15,7 +15,6 @@ package Bugzilla::Install::Requirements;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(install_string bin_loc
@ -23,6 +22,13 @@ use Bugzilla::Install::Util qw(install_string bin_loc
use List::Util qw(max);
use Term::ANSIColor;
# Return::Value 1.666002 pollutes the error log with warnings about this
# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send
# in have_vers() to disable these warnings.
BEGIN {
$Return::Value::NO_CLUCK = 1;
}
use parent qw(Exporter);
our @EXPORT = qw(
REQUIRED_MODULES
@ -124,11 +130,12 @@ sub REQUIRED_MODULES {
module => 'Template',
version => '2.24'
},
# 1.300011 has a debug mode for SMTP and automatically pass -i to sendmail.
# 2.04 implement the "Test" method (to write to data/mailer.testfile).
{
package => 'Email-Sender',
module => 'Email::Sender',
version => '1.300011',
package => 'Email-Send',
module => 'Email::Send',
version => ON_WINDOWS ? '2.16' : '2.04',
blacklist => ['^2\.196$']
},
{
package => 'Email-MIME',
@ -158,12 +165,6 @@ sub REQUIRED_MODULES {
module => 'File::Slurp',
version => '9999.13',
},
{
package => 'JSON-XS',
module => 'JSON::XS',
# 2.0 is the first version that will work with JSON::RPC.
version => '2.01',
},
);
if (ON_WINDOWS) {
@ -296,6 +297,13 @@ sub OPTIONAL_MODULES {
version => 0,
feature => ['jsonrpc', 'rest'],
},
{
package => 'JSON-XS',
module => 'JSON::XS',
# 2.0 is the first version that will work with JSON::RPC.
version => '2.0',
feature => ['jsonrpc_faster'],
},
{
package => 'Test-Taint',
module => 'Test::Taint',
@ -349,8 +357,8 @@ sub OPTIONAL_MODULES {
{
package => 'TheSchwartz',
module => 'TheSchwartz',
# 1.10 supports declining of jobs.
version => 1.10,
# 1.07 supports the prioritization of jobs.
version => 1.07,
feature => ['jobqueue'],
},
{
@ -396,22 +404,6 @@ sub OPTIONAL_MODULES {
version => '0',
feature => ['memcached'],
},
# Markdown
{
package => 'Text-Markdown',
module => 'Text::Markdown',
version => '1.0.26',
feature => ['markdown'],
},
# Documentation
{
package => 'File-Copy-Recursive',
module => 'File::Copy::Recursive',
version => 0,
feature => ['documentation'],
}
);
my $extra_modules = _get_extension_requirements('OPTIONAL_MODULES');
@ -435,7 +427,6 @@ use constant FEATURE_FILES => (
'Bugzilla/JobQueue/*', 'jobqueue.pl'],
patch_viewer => ['Bugzilla/Attachment/PatchReader.pm'],
updates => ['Bugzilla/Update.pm'],
markdown => ['Bugzilla/Markdown.pm'],
memcached => ['Bugzilla/Memcache.pm'],
);

View File

@ -13,7 +13,6 @@ package Bugzilla::Install::Util;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;

View File

@ -9,14 +9,23 @@ package Bugzilla::Job::BugMail;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::BugMail;
BEGIN { eval "use parent qw(Bugzilla::Job::Mailer)"; }
sub process_job {
my ($class, $arg) = @_;
Bugzilla::BugMail::dequeue($arg->{vars});
sub work {
my ($class, $job) = @_;
my $success = eval {
Bugzilla::BugMail::dequeue($job->arg->{vars});
1;
};
if (!$success) {
$job->failed($@);
undef $@;
}
else {
$job->completed;
}
}
1;

View File

@ -9,9 +9,7 @@ package Bugzilla::Job::Mailer;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Mailer;
BEGIN { eval "use parent qw(TheSchwartz::Worker)"; }
@ -33,24 +31,15 @@ sub retry_delay {
sub work {
my ($class, $job) = @_;
eval { $class->process_job($job->arg) };
if (my $error = $@) {
if ($error eq EMAIL_LIMIT_EXCEPTION) {
$job->declined();
}
else {
$job->failed($error);
}
my $msg = $job->arg->{msg};
my $success = eval { MessageToMTA($msg, 1); 1; };
if (!$success) {
$job->failed($@);
undef $@;
}
}
else {
$job->completed;
}
}
sub process_job {
my ($class, $arg) = @_;
MessageToMTA($arg->{msg}, 1);
}
1;

View File

@ -9,7 +9,6 @@ package Bugzilla::JobQueue;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Error;

View File

@ -13,7 +13,6 @@ package Bugzilla::JobQueue::Runner;
use 5.10.1;
use strict;
use warnings;
use Cwd qw(abs_path);
use File::Basename;
@ -80,7 +79,6 @@ sub gd_more_opt {
return (
'pidfile=s' => \$self->{gd_args}{pidfile},
'n=s' => \$self->{gd_args}{progname},
'j=s@' => \$self->{gd_args}{job_name},
);
}
@ -211,12 +209,10 @@ sub gd_run {
sub _do_work {
my ($self, $fn) = @_;
my @job_name = @{ $self->{gd_args}{job_name} // [] };
my $jq = Bugzilla->job_queue();
$jq->set_verbose($self->{debug});
$jq->set_pidfile($self->{gd_pidfile});
while (my ($key, $module) = each %{ Bugzilla::JobQueue->job_map() }) {
next if @job_name and ! grep { $_ eq $key } @job_name;
foreach my $module (values %{ Bugzilla::JobQueue->job_map() }) {
eval "use $module";
$jq->can_do($module);
}

View File

@ -9,7 +9,6 @@ package Bugzilla::Keyword;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);

View File

@ -9,7 +9,6 @@ package Bugzilla::Mailer;
use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
@Bugzilla::Mailer::EXPORT = qw(MessageToMTA build_thread_marker);
@ -23,26 +22,26 @@ use Date::Format qw(time2str);
use Encode qw(encode);
use Encode::MIME::Header;
use Email::Address;
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::Persistent;
use Bugzilla::Sender::Transport::Sendmail;
# Return::Value 1.666002 pollutes the error log with warnings about this
# deprecated module. We have to set NO_CLUCK = 1 before loading Email::Send
# to disable these warnings.
BEGIN {
$Return::Value::NO_CLUCK = 1;
}
use Email::Send;
sub MessageToMTA {
my ($msg, $send_now) = (@_);
my $method = Bugzilla->params->{'mail_delivery_method'};
return if $method eq 'None';
if (Bugzilla->params->{'use_mailer_queue'}
&& ! $send_now
&& ! Bugzilla->dbh->bz_in_transaction()
) {
if (Bugzilla->params->{'use_mailer_queue'} and !$send_now) {
Bugzilla->job_queue->insert('send_mail', { msg => $msg });
return;
}
my $dbh = Bugzilla->dbh;
my $email;
if (ref $msg) {
$email = $msg;
@ -52,58 +51,12 @@ sub MessageToMTA {
# Email::MIME doesn't do this for us. We use \015 (CR) and \012 (LF)
# directly because Perl translates "\n" depending on what platform
# you're running on. See http://perldoc.perl.org/perlport.html#Newlines
# We check for multiple CRs because of this Template-Toolkit bug:
# https://rt.cpan.org/Ticket/Display.html?id=43345
$msg =~ s/(?:\015+)?\012/\015\012/msg;
$email = new Email::MIME($msg);
}
# If we're called from within a transaction, we don't want to send the
# email immediately, in case the transaction is rolled back. Instead we
# insert it into the mail_staging table, and bz_commit_transaction calls
# send_staged_mail() after the transaction is committed.
if (! $send_now && $dbh->bz_in_transaction()) {
# The e-mail string may contain tainted values.
my $string = $email->as_string;
trick_taint($string);
$dbh->do("INSERT INTO mail_staging (message) VALUES(?)", undef, $string);
return;
}
# Ensure that we are not sending emails too quickly to recipients.
if (Bugzilla->params->{use_mailer_queue}
&& (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR))
{
$dbh->do(
"DELETE FROM email_rates WHERE message_ts < "
. $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'HOUR'));
my $recipient = $email->header('To');
if (EMAIL_LIMIT_PER_MINUTE) {
my $minute_rate = $dbh->selectrow_array(
"SELECT COUNT(*)
FROM email_rates
WHERE recipient = ? AND message_ts >= "
. $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'MINUTE'),
undef,
$recipient);
if ($minute_rate >= EMAIL_LIMIT_PER_MINUTE) {
die EMAIL_LIMIT_EXCEPTION;
}
}
if (EMAIL_LIMIT_PER_HOUR) {
my $hour_rate = $dbh->selectrow_array(
"SELECT COUNT(*)
FROM email_rates
WHERE recipient = ? AND message_ts >= "
. $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', '1', 'HOUR'),
undef,
$recipient);
if ($hour_rate >= EMAIL_LIMIT_PER_HOUR) {
die EMAIL_LIMIT_EXCEPTION;
}
}
}
# We add this header to uniquely identify all email that we
# send as coming from this Bugzilla installation.
#
@ -111,7 +64,7 @@ sub MessageToMTA {
# *always* be the same for this Bugzilla, in every email,
# even if the admin changes the "ssl_redirect" parameter some day.
$email->header_set('X-Bugzilla-URL', Bugzilla->params->{'urlbase'});
# We add this header to mark the mail as "auto-generated" and
# thus to hopefully avoid auto replies.
$email->header_set('Auto-Submitted', 'auto-generated');
@ -139,14 +92,21 @@ sub MessageToMTA {
my $from = $email->header('From');
my $hostname;
my $transport;
my ($hostname, @args);
my $mailer_class = $method;
if ($method eq "Sendmail") {
$mailer_class = 'Bugzilla::Send::Sendmail';
if (ON_WINDOWS) {
$transport = Bugzilla::Sender::Transport::Sendmail->new({ sendmail => SENDMAIL_EXE });
$Email::Send::Sendmail::SENDMAIL = SENDMAIL_EXE;
}
else {
$transport = Bugzilla::Sender::Transport::Sendmail->new();
push @args, "-i";
# We want to make sure that we pass *only* an email address.
if ($from) {
my ($email_obj) = Email::Address->parse($from);
if ($email_obj) {
my $from_email = $email_obj->address;
push(@args, "-f$from_email") if $from_email;
}
}
}
else {
@ -154,7 +114,7 @@ sub MessageToMTA {
# address, but other mailers won't.
my $urlbase = Bugzilla->params->{'urlbase'};
$urlbase =~ m|//([^:/]+)[:/]?|;
$hostname = $1 || 'localhost';
$hostname = $1;
$from .= "\@$hostname" if $from !~ /@/;
$email->header_set('From', $from);
@ -165,19 +125,16 @@ sub MessageToMTA {
}
if ($method eq "SMTP") {
my ($host, $port) = split(/:/, Bugzilla->params->{'smtpserver'}, 2);
$transport = Bugzilla->request_cache->{smtp} //=
Email::Sender::Transport::SMTP::Persistent->new({
host => $host,
defined($port) ? (port => $port) : (),
sasl_username => Bugzilla->params->{'smtp_username'},
sasl_password => Bugzilla->params->{'smtp_password'},
helo => $hostname,
ssl => Bugzilla->params->{'smtp_ssl'},
debug => Bugzilla->params->{'smtp_debug'} });
push @args, Host => Bugzilla->params->{"smtpserver"},
username => Bugzilla->params->{"smtp_username"},
password => Bugzilla->params->{"smtp_password"},
Hello => $hostname,
ssl => Bugzilla->params->{'smtp_ssl'},
Debug => Bugzilla->params->{'smtp_debug'};
}
Bugzilla::Hook::process('mailer_before_send', { email => $email });
Bugzilla::Hook::process('mailer_before_send',
{ email => $email, mailer_args => \@args });
return if $email->header('to') eq '';
@ -212,23 +169,13 @@ sub MessageToMTA {
close TESTFILE;
}
else {
# This is useful for Sendmail, so we put it out here.
# This is useful for both Sendmail and Qmail, so we put it out here.
local $ENV{PATH} = SENDMAIL_PATH;
eval { sendmail($email, { transport => $transport }) };
if ($@) {
ThrowCodeError('mail_send_error', { msg => $@->message, mail => $email });
}
}
# insert into email_rates
if (Bugzilla->params->{use_mailer_queue}
&& (EMAIL_LIMIT_PER_MINUTE || EMAIL_LIMIT_PER_HOUR))
{
$dbh->do(
"INSERT INTO email_rates(recipient, message_ts) VALUES (?, LOCALTIMESTAMP(0))",
undef,
$email->header('To')
);
my $mailer = Email::Send->new({ mailer => $mailer_class,
mailer_args => \@args });
my $retval = $mailer->send($email);
ThrowCodeError('mail_send_error', { msg => $retval, mail => $email })
if !$retval;
}
}
@ -261,50 +208,14 @@ sub build_thread_marker {
return $threadingmarker;
}
sub send_staged_mail {
my $dbh = Bugzilla->dbh;
my @ids;
my $emails
= $dbh->selectall_arrayref("SELECT id, message FROM mail_staging");
foreach my $row (@$emails) {
MessageToMTA($row->[1]);
push(@ids, $row->[0]);
}
if (@ids) {
$dbh->do("DELETE FROM mail_staging WHERE " . $dbh->sql_in('id', \@ids));
}
}
1;
__END__
=head1 NAME
Bugzilla::Mailer - Provides methods for sending email
=head1 METHODS
=head1 B<Methods in need of POD>
=over
=item C<MessageToMTA>
=item build_thread_marker
Sends the passed message to the mail transfer agent.
The actual behaviour depends on a number of factors: if called from within a
database transaction, the message will be staged and sent when the transaction
is committed. If email queueing is enabled, the message will be sent to
TheSchwartz job queue where it will be processed by the jobqueue daemon, else
the message is sent immediately.
=item C<build_thread_marker>
Builds header suitable for use as a threading marker in email notifications.
=item C<send_staged_mail>
Sends all staged messages -- called after a database transaction is committed.
=item MessageToMTA
=back

View File

@ -1,520 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
package Bugzilla::Markdown;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Template;
use Digest::MD5 qw(md5_hex);
use parent qw(Text::Markdown);
@Bugzilla::Markdown::EXPORT = qw(new);
# Regex to match balanced [brackets]. See Friedl's
# "Mastering Regular Expressions", 2nd Ed., pp. 328-331.
our ($g_nested_brackets, $g_nested_parens);
$g_nested_brackets = qr{
(?> # Atomic matching
[^\[\]]+ # Anything other than brackets
|
\[
(??{ $g_nested_brackets }) # Recursive set of nested brackets
\]
)*
}x;
# Doesn't allow for whitespace, because we're using it to match URLs:
$g_nested_parens = qr{
(?> # Atomic matching
[^()\s]+ # Anything other than parens or whitespace
|
\(
(??{ $g_nested_parens }) # Recursive set of nested brackets
\)
)*
}x;
our %g_escape_table;
foreach my $char (split //, '\\`*_{}[]()>#+-.!~') {
$g_escape_table{$char} = md5_hex($char);
}
$g_escape_table{'&lt;'} = md5_hex('&lt;');
sub new {
my $invocant = shift;
my $class = ref $invocant || $invocant;
return $class->SUPER::new(tab_width => MARKDOWN_TAB_WIDTH,
# Bugzilla uses HTML not XHTML
empty_element_suffix => '>');
}
sub markdown {
my $self = shift;
my $text = shift;
my $user = Bugzilla->user;
if ($user->settings->{use_markdown}->{is_enabled}
&& $user->setting('use_markdown') eq 'on')
{
return $self->SUPER::markdown($text, @_);
}
return Bugzilla::Template::quoteUrls($text);
}
sub _Markdown {
my $self = shift;
my $text = shift;
$text = Bugzilla::Template::quoteUrls($text, undef, undef, undef, undef, 1);
return $self->SUPER::_Markdown($text, @_);
}
sub _RunSpanGamut {
# These are all the transformations that occur *within* block-level
# tags like paragraphs, headers, and list items.
my ($self, $text) = @_;
$text = $self->_DoCodeSpans($text);
$text = $self->_EscapeSpecialCharsWithinTagAttributes($text);
$text = $self->_EscapeSpecialChars($text);
$text = $self->_DoAnchors($text);
# Strikethroughs is Bugzilla's extension
$text = $self->_DoStrikethroughs($text);
$text = $self->_DoAutoLinks($text);
$text = $self->_EncodeAmpsAndAngles($text);
$text = $self->_DoItalicsAndBold($text);
$text =~ s/\n/<br$self->{empty_element_suffix}\n/g;
return $text;
}
# Override to check for HTML-escaped <>" chars.
sub _StripLinkDefinitions {
#
# Strips link definitions from text, stores the URLs and titles in
# hash references.
#
my ($self, $text) = @_;
my $less_than_tab = $self->{tab_width} - 1;
# Link defs are in the form: ^[id]: url "optional title"
while ($text =~ s{
^[ ]{0,$less_than_tab}\[(.+)\]: # id = \$1
[ \t]*
\n? # maybe *one* newline
[ \t]*
(?:&lt;)?<a\s+href="(.+?)">\2</a>(?:&gt;)? # url = \$2
[ \t]*
\n? # maybe one newline
[ \t]*
(?:
(?<=\s) # lookbehind for whitespace
(?:&quot;|\()
(.+?) # title = \$3
(?:&quot;|\))
[ \t]*
)? # title is optional
(?:\n+|\Z)
}{}omx) {
$self->{_urls}{lc $1} = $self->_EncodeAmpsAndAngles( $2 ); # Link IDs are case-insensitive
if ($3) {
$self->{_titles}{lc $1} = $3;
$self->{_titles}{lc $1} =~ s/"/&quot;/g;
}
}
return $text;
}
# We need to look for HTML-escaped '<' and '>' (i.e. &lt; and &gt;).
# We also remove Email linkification from the original implementation
# as it is already done in Bugzilla's quoteUrls().
sub _DoAutoLinks {
my ($self, $text) = @_;
$text =~ s{(?:<|&lt;)((?:https?|ftp):[^'">\s]+?)(?:>|&gt;)}{<a href="$1">$1</a>}gi;
return $text;
}
# The main reasons for overriding this method are
# resolving URL conflicts with Bugzilla's quoteUrls()
# and also changing '"' to '&quot;' in regular expressions wherever needed.
sub _DoAnchors {
#
# Turn Markdown link shortcuts into <a> tags.
#
my ($self, $text) = @_;
# We revert linkifications of non-email links and only
# those links whose URL and title are the same because
# this way we can be sure that link is generated by quoteUrls()
$text =~ s@<a \s+ href="(?! mailto ) (.+?)">\1</a>@$1@xmg;
#
# First, handle reference-style links: [link text] [id]
#
$text =~ s{
( # wrap whole match in $1
\[
($g_nested_brackets) # link text = $2
\]
[ ]? # one optional space
(?:\n[ ]*)? # one optional newline followed by spaces
\[
(.*?) # id = $3
\]
)
}{
my $whole_match = $1;
my $link_text = $2;
my $link_id = lc $3;
if ($link_id eq "") {
$link_id = lc $link_text; # for shortcut links like [this][].
}
$link_id =~ s{[ ]*\n}{ }g; # turn embedded newlines into spaces
$self->_GenerateAnchor($whole_match, $link_text, $link_id);
}xsge;
#
# Next, inline-style links: [link text](url "optional title")
#
$text =~ s{
( # wrap whole match in $1
\[
($g_nested_brackets) # link text = $2
\]
\( # literal paren
[ \t]*
($g_nested_parens) # href = $3
[ \t]*
( # $4
(&quot;|') # quote char = $5
(.*?) # Title = $6
\5 # matching quote
[ \t]* # ignore any spaces/tabs between closing quote and )
)? # title is optional
\)
)
}{
my $result;
my $whole_match = $1;
my $link_text = $2;
my $url = $3;
my $title = $6;
# Remove Bugzilla quoteUrls() linkification
if ($url =~ /^a href="/ && $url =~ m|</a$|) {
$url =~ s/^[^>]+>//;
$url =~ s@</a$@@;
}
# Limit URL to HTTP/HTTPS links
$url = "http://$url" unless $url =~ m!^https?://!i;
$self->_GenerateAnchor($whole_match, $link_text, undef, $url, $title);
}xsge;
#
# Last, handle reference-style shortcuts: [link text]
# These must come last in case you've also got [link test][1]
# or [link test](/foo)
#
$text =~ s{
( # wrap whole match in $1
\[
([^\[\]]+) # link text = $2; can't contain '[' or ']'
\]
)
}{
my $result;
my $whole_match = $1;
my $link_text = $2;
(my $link_id = lc $2) =~ s{[ ]*\n}{ }g; # lower-case and turn embedded newlines into spaces
$self->_GenerateAnchor($whole_match, $link_text, $link_id);
}xsge;
return $text;
}
# The purpose of overriding this function is to add support
# for a Github Flavored Markdown (GFM) feature called 'Multiple
# underscores in words'. The standard markdown specification
# specifies the underscore for making the text emphasized/bold.
# However, some variable names in programming languages contain underscores
# and we do not want a part of those variables to look emphasized/bold.
# Instead, we render them as the way they originally are.
sub _DoItalicsAndBold {
my ($self, $text) = @_;
# Handle at beginning of lines:
$text =~ s{ (^__ (?=\S) (.+?[*_]*) (?<=\S) __ (?!\S)) }
{
my $result = _has_multiple_underscores($2) ? $1 : "<strong>$2</strong>";
$result;
}gsxe;
$text =~ s{ ^\*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{<strong>$1</strong>}gsx;
$text =~ s{ (^_ (?=\S) (.+?) (?<=\S) _ (?!\S)) }
{
my $result = _has_multiple_underscores($2) ? $1 : "<em>$2</em>";
$result;
}gsxe;
$text =~ s{ ^\* (?=\S) (.+?) (?<=\S) \* }{<em>$1</em>}gsx;
# <strong> must go first:
$text =~ s{ ( (?<=\W) __ (?=\S) (.+?[*_]*) (?<=\S) __ (?!\S) ) }
{
my $result = _has_multiple_underscores($2) ? $1 : "<strong>$2</strong>";
$result;
}gsxe;
$text =~ s{ (?<=\W) \*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{<strong>$1</strong>}gsx;
$text =~ s{ ( (?<=\W) _ (?=\S) (.+?) (?<=\S) _ (?!\S) ) }
{
my $result = _has_multiple_underscores($2) ? $1 : "<em>$2</em>";
$result;
}gsxe;
$text =~ s{ (?<=\W) \* (?=\S) (.+?) (?<=\S) \* }{<em>$1</em>}gsx;
# And now, a second pass to catch nested strong and emphasis special cases
$text =~ s{ ( (?<=\W) __ (?=\S) (.+?[*_]*) (?<=\S) __ (\S*) ) }
{
my $result = _has_multiple_underscores($3) ? $1 : "<strong>$2</strong>$3";
$result;
}gsxe;
$text =~ s{ (?<=\W) \*\* (?=\S) (.+?[*_]*) (?<=\S) \*\* }{<strong>$1</strong>}gsx;
$text =~ s{ ( (?<=\W) _ (?=\S) (.+?) (?<=\S) _ (\S*) ) }
{
my $result = _has_multiple_underscores($3) ? $1 : "<em>$2</em>$3";
$result;
}gsxe;
$text =~ s{ (?<=\W) \* (?=\S) (.+?) (?<=\S) \* }{<em>$1</em>}gsx;
return $text;
}
sub _DoStrikethroughs {
my ($self, $text) = @_;
$text =~ s{ ^ ~~ (?=\S) ([^~]+?) (?<=\S) ~~ (?!~) }{<del>$1</del>}gsx;
$text =~ s{ (?<=_|[^~\w]) ~~ (?=\S) ([^~]+?) (?<=\S) ~~ (?!~) }{<del>$1</del>}gsx;
return $text;
}
# The original _DoCodeSpans() uses the 's' modifier in its regex
# which prevents _DoCodeBlocks() to match GFM fenced code blocks.
# We copy the code from the original implementation and remove the
# 's' modifier from it.
sub _DoCodeSpans {
my ($self, $text) = @_;
$text =~ s@
(?<!\\) # Character before opening ` can't be a backslash
(`+) # $1 = Opening run of `
(.+?) # $2 = The code block
(?<!`)
\1 # Matching closer
(?!`)
@
my $c = "$2";
$c =~ s/^[ \t]*//g; # leading whitespace
$c =~ s/[ \t]*$//g; # trailing whitespace
$c = $self->_EncodeCode($c);
"<code>$c</code>";
@egx;
return $text;
}
# Override to add GFM Fenced Code Blocks
sub _DoCodeBlocks {
my ($self, $text) = @_;
$text =~ s{
^ `{3,} [\s\t]* \n
( # $1 = the entire code block
(?: .* \n+)+?
)
`{3,} [\s\t]* $
}{
my $codeblock = $1;
my $result;
$codeblock = $self->_EncodeCode($codeblock);
$codeblock = $self->_Detab($codeblock);
$codeblock =~ s/\n\z//; # remove the trailing newline
$result = "\n\n<pre><code>" . $codeblock . "</code></pre>\n\n";
$result;
}egmx;
# And now do the standard code blocks
$text = $self->SUPER::_DoCodeBlocks($text);
return $text;
}
sub _DoBlockQuotes {
my ($self, $text) = @_;
$text =~ s{
( # Wrap whole match in $1
(?:
^[ \t]*&gt;[ \t]? # '>' at the start of a line
.+\n # rest of the first line
(?:.+\n)* # subsequent consecutive lines
\n* # blanks
)+
)
}{
my $bq = $1;
$bq =~ s/^[ \t]*&gt;[ \t]?//gm; # trim one level of quoting
$bq =~ s/^[ \t]+$//mg; # trim whitespace-only lines
$bq = $self->_RunBlockGamut($bq, {wrap_in_p_tags => 1}); # recurse
$bq =~ s/^/ /mg;
# These leading spaces screw with <pre> content, so we need to fix that:
$bq =~ s{(\s*<pre>.+?</pre>)}{
my $pre = $1;
$pre =~ s/^ //mg;
$pre;
}egs;
"<blockquote>\n$bq\n</blockquote>\n\n";
}egmx;
return $text;
}
sub _EncodeCode {
my ($self, $text) = @_;
# We need to unescape the escaped HTML characters in code blocks.
# These are the reverse of the escapings done in Bugzilla::Util::html_quote()
$text =~ s/&lt;/</g;
$text =~ s/&gt;/>/g;
$text =~ s/&quot;/"/g;
$text =~ s/&#64;/@/g;
# '&amp;' substitution must be the last one, otherwise a literal like '&gt;'
# will turn to '>' because '&' is already changed to '&amp;' in Bugzilla::Util::html_quote().
# In other words, html_quote() will change '&gt;' to '&amp;gt;' and then we will
# change '&amp;gt' -> '&gt;' -> '>' if we write this substitution as the first one.
$text =~ s/&amp;/&/g;
$text =~ s{<a \s+ href="(?:mailto:)? (.+?)"> \1 </a>}{$1}xmgi;
$text = $self->SUPER::_EncodeCode($text);
$text =~ s/~/$g_escape_table{'~'}/go;
# Encode '&lt;' to prevent URLs from getting linkified in code spans
$text =~ s/&lt;/$g_escape_table{'&lt;'}/go;
return $text;
}
sub _EncodeBackslashEscapes {
my ($self, $text) = @_;
$text = $self->SUPER::_EncodeBackslashEscapes($text);
$text =~ s/\\~/$g_escape_table{'~'}/go;
return $text;
}
sub _UnescapeSpecialChars {
my ($self, $text) = @_;
$text = $self->SUPER::_UnescapeSpecialChars($text);
$text =~ s/$g_escape_table{'~'}/~/go;
$text =~ s/$g_escape_table{'&lt;'}/&lt;/go;
return $text;
}
# Check if the passed string is of the form multiple_underscores_in_a_word.
# To check that, we first need to make sure that the string does not contain
# any white-space. Then, if the string is composed of non-space chunks which
# are bound together with underscores, the string has the desired form.
sub _has_multiple_underscores {
my $string = shift;
return 0 unless defined($string) && length($string);
return 0 if $string =~ /[\t\s]+/;
return 1 if scalar (split /_/, $string) > 1;
return 0;
}
1;
__END__
=head1 NAME
Bugzilla::Markdown - Generates HTML output from structured plain-text input.
=head1 SYNOPSIS
use Bugzilla::Markdown;
my $markdown = Bugzilla::Markdown->new();
print $markdown->markdown($text);
=head1 DESCRIPTION
Bugzilla::Markdown implements a Markdown engine that produces
an HTML-based output from a given plain-text input.
The majority of the implementation is done by C<Text::Markdown>
CPAN module. It also applies the linkifications done in L<Bugzilla::Template>
to the input resulting in an output which is a combination of both Markdown
structures and those defined by Bugzilla itself.
=head2 Accessors
=over
=item C<markdown>
C<string> Produces an HTML-based output string based on the structures
and format defined in the given plain-text input.
=over
=item B<Params>
=over
=item C<text>
C<string> A plain-text string which includes Markdown structures.
=back
=back
=back

View File

@ -254,13 +254,10 @@ sub _get {
elsif (ref($value) eq 'ARRAY') {
foreach my $value (@$value) {
next unless defined $value;
# arrays of hashes and arrays are common
# arrays of hashes are common
if (ref($value) eq 'HASH') {
_detaint_hashref($value);
}
elsif (ref($value) eq 'ARRAY') {
_detaint_arrayref($value);
}
elsif (!ref($value)) {
trick_taint($value);
}
@ -281,15 +278,6 @@ sub _detaint_hashref {
}
}
sub _detaint_arrayref {
my ($arrayref) = @_;
foreach my $value (@$arrayref) {
if (defined($value) && !ref($value)) {
trick_taint($value);
}
}
}
sub _delete {
my ($self, $key) = @_;
$key = $self->_encode_key($key)

View File

@ -9,7 +9,6 @@ package Bugzilla::Migrate;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Attachment;
use Bugzilla::Bug qw(LogActivityEntry);

View File

@ -9,7 +9,6 @@ package Bugzilla::Migrate::Gnats;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Migrate);

View File

@ -9,7 +9,6 @@ package Bugzilla::Milestone;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);

View File

@ -9,7 +9,6 @@ package Bugzilla::Object;
use 5.10.1;
use strict;
use warnings;
use Bugzilla::Constants;
use Bugzilla::Hook;

View File

@ -9,7 +9,6 @@ package Bugzilla::Product;
use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);

Some files were not shown because too many files have changed in this diff Show More