diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 148477f34..66f9f73a5 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -534,7 +534,8 @@ sub _check_content_type { my ($invocant, $content_type) = @_; $content_type = 'text/plain' if (ref $invocant && ($invocant->isurl || $invocant->ispatch)); - if (!_legal_content_type($content_type)) { + $content_type = trim($content_type); + if (!$content_type || !_legal_content_type($content_type)) { ThrowUserError("invalid_content_type", { contenttype => $content_type }); } trick_taint($content_type); diff --git a/Bugzilla/Auth.pm b/Bugzilla/Auth.pm index cf7d27f98..07e48ead0 100644 --- a/Bugzilla/Auth.pm +++ b/Bugzilla/Auth.pm @@ -155,7 +155,12 @@ sub _handle_login_result { } } elsif ($fail_code == AUTH_ERROR) { - ThrowCodeError($result->{error}, $result->{details}); + if ($result->{user_error}) { + ThrowUserError($result->{user_error}, $result->{details}); + } + else { + ThrowCodeError($result->{error}, $result->{details}); + } } elsif ($fail_code == AUTH_NODATA) { $self->{_info_getter}->fail_nodata($self) diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm index d8794472e..2fcfd4017 100644 --- a/Bugzilla/Auth/Verify/DB.pm +++ b/Bugzilla/Auth/Verify/DB.pm @@ -74,6 +74,12 @@ sub check_credentials { }; } + # 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 # password tokens or login failures they may have generated. Bugzilla::Token::DeletePasswordTokens($user->id, "user_logged_in"); diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index d3edb11be..808ae42a4 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -1326,7 +1326,7 @@ sub _check_dependencies { my %deps_in = (dependson => $depends_on || '', blocked => $blocks || ''); - foreach my $type qw(dependson blocked) { + foreach my $type (qw(dependson blocked)) { my @bug_ids = ref($deps_in{$type}) ? @{$deps_in{$type}} : split(/[\s,]+/, $deps_in{$type}); @@ -2525,6 +2525,15 @@ sub add_see_also { ThrowUserError('bug_url_invalid', { url => $input, reason => 'http' }); } + # This stops the following edge cases from being accepted: + # * show_bug.cgi?id=1 + # * /show_bug.cgi?id=1 + # * http:///show_bug.cgi?id=1 + if (!$uri->authority or $uri->path !~ m{/}) { + ThrowUserError('bug_url_invalid', + { url => $input, reason => 'path_only' }); + } + my $result; # Launchpad URLs if ($uri->authority =~ /launchpad.net$/) { diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index 61e4aaa9e..29263dcdb 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -178,9 +178,7 @@ sub clean_search_url { foreach my $num (1,2) { # If there's no value in the email field, delete the related fields. if (!$self->param("email$num")) { - foreach my $field qw(type assigned_to reporter qa_contact - cc longdesc) - { + foreach my $field (qw(type assigned_to reporter qa_contact cc longdesc)) { $self->delete("email$field$num"); } } @@ -227,7 +225,8 @@ sub multipart_init { } # Set the MIME boundary and content-type - my $boundary = $param{'-boundary'} || '------- =_aaaaaaaaaa0'; + my $boundary = $param{'-boundary'} + || '------- =_' . generate_random_password(16); delete $param{'-boundary'}; $self->{'separator'} = "\r\n--$boundary\r\n"; $self->{'final_separator'} = "\r\n--$boundary--\r\n"; diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm index d8e04fd9a..86b57dd71 100644 --- a/Bugzilla/Component.pm +++ b/Bugzilla/Component.pm @@ -401,16 +401,15 @@ sub flag_types if (!defined $self->{'flag_types'}) { + my $flagtypes = Bugzilla::FlagType::match({ product_id => $self->product_id, + component_id => $self->id }); + $self->{'flag_types'} = {}; $self->{'flag_types'}->{'bug'} = - Bugzilla::FlagType::match({ 'target_type' => 'bug', - 'product_id' => $self->product_id, - 'component_id' => $self->id }); + [grep { $_->target_type eq 'bug' } @$flagtypes]; $self->{'flag_types'}->{'attachment'} = - Bugzilla::FlagType::match({ 'target_type' => 'attachment', - 'product_id' => $self->product_id, - 'component_id' => $self->id }); + [grep { $_->target_type eq 'attachment' } @$flagtypes]; foreach my $type (@{$self->{flag_types}->{bug}}, @{$self->{flag_types}->{attachment}}) { diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 096d16e4f..4f25e8202 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -185,7 +185,7 @@ use Cwd qw(abs_path); # CONSTANTS # # Bugzilla version -use constant BUGZILLA_VERSION => "3.6.2"; +use constant BUGZILLA_VERSION => "3.6.3"; # 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 @@ -552,6 +552,7 @@ sub bz_locations { 'datadir' => "$libpath/$datadir", 'attachdir' => "$libpath/$datadir/attachments", 'skinsdir' => "$libpath/skins", + 'graphsdir' => "$libpath/graphs", # $webdotdir must be in the web server's tree somewhere. Even if you use a # local dot, we output images to there. Also, if $webdotdir is # not relative to the bugzilla root directory, you'll need to diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 0824eaf0c..4dde9b211 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -309,8 +309,7 @@ Params: =over -=item C - The changed bug object, with all fields set to their updated -values. +=item C - The created bug object. =item C - The timestamp used for all updates in this transaction, as a SQL date string. @@ -784,6 +783,27 @@ The value being set on the object. =back +=head2 object_end_of_create + +Called at the end of L, after all other changes are +made to the database. This occurs inside a database transaction. + +Params: + +=over + +=item C + +The name of the class that C was called on. You can check this +like C<< if ($class->isa('Some::Class')) >> in your code, to perform specific +tasks for only certain classes. + +=item C + +The created object. + +=back + =head2 object_end_of_create_validators Called at the end of L. You can diff --git a/Bugzilla/Install/CPAN.pm b/Bugzilla/Install/CPAN.pm index 52f762a9a..bdf1d5f05 100644 --- a/Bugzilla/Install/CPAN.pm +++ b/Bugzilla/Install/CPAN.pm @@ -149,6 +149,9 @@ sub install_module { } my $module = CPAN::Shell->expand('Module', $name); + if (!$module) { + die install_string('no_such_module', { module => $name }) . "\n"; + } print install_string('install_module', { module => $name, version => $module->cpan_version }) . "\n"; if ($test) { diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index 09c1a7695..957c50e74 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -74,6 +74,7 @@ sub FILESYSTEM { my $extlib = bz_locations()->{'ext_libpath'}; my $skinsdir = bz_locations()->{'skinsdir'}; my $localconfig = bz_locations()->{'localconfig'}; + my $graphsdir = bz_locations()->{'graphsdir'}; # We want to set the permissions the same for all localconfig files # across all PROJECTs, so we do something special with $localconfig, @@ -177,7 +178,7 @@ sub FILESYSTEM { dirs => $ws_dir_writeable }, $webdotdir => { files => $ws_writeable, dirs => $ws_dir_writeable }, - graphs => { files => $ws_writeable, + $graphsdir => { files => $ws_writeable, dirs => $ws_dir_writeable }, # Readable directories @@ -233,7 +234,7 @@ sub FILESYSTEM { "$datadir/extensions" => $ws_dir_readable, $attachdir => $ws_dir_writeable, $extensionsdir => $ws_dir_readable, - graphs => $ws_dir_writeable, + $graphsdir => $ws_dir_writeable, $webdotdir => $ws_dir_writeable, "$skinsdir/custom" => $ws_dir_readable, "$skinsdir/contrib" => $ws_dir_readable, @@ -336,8 +337,17 @@ EOT # in a subdirectory. deny from all EOT + }, + "$graphsdir/.htaccess" => { perms => $ws_readable, contents => < + Allow from all + +# And no directory listings, either. +Deny from all +EOT }, ); @@ -363,10 +373,11 @@ sub update_filesystem { my %files = %{$fs->{create_files}}; my $datadir = bz_locations->{'datadir'}; + my $graphsdir = bz_locations->{'graphsdir'}; # If the graphs/ directory doesn't exist, we're upgrading from # a version old enough that we need to update the $datadir/mining # format. - if (-d "$datadir/mining" && !-d 'graphs') { + if (-d "$datadir/mining" && !-d $graphsdir) { _update_old_charts($datadir); } diff --git a/Bugzilla/Install/Util.pm b/Bugzilla/Install/Util.pm index f0523c2f6..f0f605b28 100644 --- a/Bugzilla/Install/Util.pm +++ b/Bugzilla/Install/Util.pm @@ -159,7 +159,14 @@ sub include_languages { my @wanted; if ($params->{only_language}) { - @wanted = ($params->{only_language}); + # We can pass several languages at once as an arrayref + # or a single language. + if (ref $params->{only_language}) { + @wanted = @{ $params->{only_language} }; + } + else { + @wanted = ($params->{only_language}); + } } else { @wanted = _sort_accept_language($ENV{'HTTP_ACCEPT_LANGUAGE'} || ''); @@ -257,7 +264,7 @@ sub _template_base_directories sub template_include_path { my ($params) = @_; - my @used_languages = include_languages(@_); + my @used_languages = include_languages($params); # Now, we add template directories in the order they will be searched: my $template_dirs = _template_base_directories(); diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index 9020a98dc..ce90ff444 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -491,7 +491,12 @@ sub insert_create_data { $dbh->do("INSERT INTO $table (" . join(', ', @field_names) . ") VALUES ($qmarks)", undef, @values); my $id = $dbh->bz_last_key($table, $class->ID_FIELD); - return $class->new($id); + + my $object = $class->new($id); + + Bugzilla::Hook::process('object_end_of_create', { class => $class, + object => $object }); + return $object; } sub get_all { diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 14fa1aba1..22af3b11a 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -401,6 +401,8 @@ sub init { } foreach my $field ($params->param()) { + # "votes" got special treatment, above. + next if $field eq 'votes'; if (grep { $_->name eq $field } @legal_fields) { my $type = $params->param("${field}_type"); if (!$type) { @@ -715,13 +717,9 @@ sub init { my $sql_deadlinefrom; my $sql_deadlineto; if ($user->is_timetracker) { - my $deadlinefrom; - my $deadlineto; - - if ($params->param('deadlinefrom')){ - $params->param('deadlinefrom', '') if lc($params->param('deadlinefrom')) eq 'now'; - $deadlinefrom = SqlifyDate($params->param('deadlinefrom')); - $sql_deadlinefrom = $dbh->quote($deadlinefrom); + if ($params->param('deadlinefrom')) { + my $deadlinefrom = $params->param('deadlinefrom'); + $sql_deadlinefrom = $dbh->quote(SqlifyDate($deadlinefrom)); trick_taint($sql_deadlinefrom); my $term = "bugs.deadline >= $sql_deadlinefrom"; push(@wherepart, $term); @@ -731,10 +729,9 @@ sub init { }); } - if ($params->param('deadlineto')){ - $params->param('deadlineto', '') if lc($params->param('deadlineto')) eq 'now'; - $deadlineto = SqlifyDate($params->param('deadlineto')); - $sql_deadlineto = $dbh->quote($deadlineto); + if ($params->param('deadlineto')) { + my $deadlineto = $params->param('deadlineto'); + $sql_deadlineto = $dbh->quote(SqlifyDate($deadlineto)); trick_taint($sql_deadlineto); my $term = "bugs.deadline <= $sql_deadlineto"; push(@wherepart, $term); @@ -1211,7 +1208,7 @@ sub init { ############################################################################### sub SqlifyDate { my ($str) = @_; - $str = "" if !defined $str; + $str = "" if (!defined $str || lc($str) eq 'now'); if ($str eq "") { my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime(time()); return sprintf("%4d-%02d-%02d 00:00:00", $year+1900, $month+1, $mday); diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm index eb961eeaa..dae68a64d 100644 --- a/Bugzilla/Search/Quicksearch.pm +++ b/Bugzilla/Search/Quicksearch.pm @@ -30,6 +30,9 @@ use Bugzilla::Status; use Bugzilla::Field; use Bugzilla::Util; +use List::Util qw(min max); +use List::MoreUtils qw(firstidx); + use base qw(Exporter); @Bugzilla::Search::Quicksearch::EXPORT = qw(quicksearch); @@ -469,18 +472,30 @@ sub _translate_field_name { sub _special_field_syntax { my $self = shift; my ($word, $negate) = @_; - + # P1-5 Syntax if ($word =~ m/^P(\d+)(?:-(\d+))?$/i) { - my $start = $1 - 1; - $start = 0 if $start < 0; - my $end = $2 - 1; - + my ($p_start, $p_end) = ($1, $2); my $legal_priorities = get_legal_field_values('priority'); - $end = scalar(@$legal_priorities) - 1 - if $end > (scalar @$legal_priorities - 1); + + # If Pn exists explicitly, use it. + my $start = firstidx { $_ eq "P$p_start" } @$legal_priorities; + my $end; + $end = firstidx { $_ eq "P$p_end" } @$legal_priorities if defined $p_end; + + # If Pn doesn't exist explicitly, then we mean the nth priority. + if ($start == -1) { + $start = max(0, $p_start - 1); + } my $prios = $legal_priorities->[$start]; - if ($end) { + + if (defined $end) { + # If Pn doesn't exist explicitly, then we mean the nth priority. + if ($end == -1) { + $end = min(scalar(@$legal_priorities), $p_end) - 1; + $end = max(0, $end); # Just in case the user typed P0. + } + ($start, $end) = ($end, $start) if $end < $start; $prios = join(',', @$legal_priorities[$start..$end]) } $self->addChart('priority', 'anyexact', $prios, $negate); @@ -492,7 +507,7 @@ sub _special_field_syntax { $self->addChart('votes', 'greaterthan', $1, $negate); return 1; } - + # Votes (votes>=xx, votes=>xx) if ($word =~ m/^votes(>=|=>)([0-9]+)$/) { $self->addChart('votes', 'greaterthan', $2-1, $negate); diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 83a5bca2e..2ac91b7ad 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -936,7 +936,8 @@ sub precompile_templates { print install_string('template_precompile') if $output; - my $paths = template_include_path({ use_languages => Bugzilla->languages }); + my $paths = template_include_path({ use_languages => Bugzilla->languages, + only_language => Bugzilla->languages }); foreach my $dir (@$paths) { my $template = Bugzilla::Template->create(include_path => [$dir]); diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm index 19d230759..f31620dfb 100644 --- a/Bugzilla/WebService/Constants.pm +++ b/Bugzilla/WebService/Constants.pm @@ -102,6 +102,7 @@ use constant WS_ERROR_CODE => { auth_invalid_email => 302, extern_id_conflict => -303, auth_failure => 304, + password_current_too_short => 305, # Except, historically, AUTH_NODATA, which is 410. login_required => 410, diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm index e084c4fe1..16c60b88d 100644 --- a/Bugzilla/WebService/User.pm +++ b/Bugzilla/WebService/User.pm @@ -321,6 +321,11 @@ The username does not exist, or the password is wrong. The account has been disabled. A reason may be specified with the error. +=item 305 (New Password Required) + +The current password is correct, but the user is asked to change +his password. + =item 50 (Param Required) A login or password parameter was not provided. diff --git a/attachment.cgi b/attachment.cgi index 380f690dd..b3885242d 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -542,6 +542,7 @@ sub insert { # Insert a comment about the new attachment into the database. my $comment = $cgi->param('comment'); + $comment = '' unless defined $comment; $bug->add_comment($comment, { isprivate => $attachment->isprivate, type => CMT_ATTACHMENT_CREATED, work_time => scalar $cgi->param('work_time'), @@ -704,7 +705,7 @@ sub update { # If the user submitted a comment while editing the attachment, # add the comment to the bug. Do this after having validated isprivate! my $comment = $cgi->param('comment'); - if (trim($comment)) { + if (defined $comment && trim($comment) ne '') { $bug->add_comment($comment, { isprivate => $attachment->isprivate, type => CMT_ATTACHMENT_UPDATED, work_time => scalar $cgi->param('work_time'), diff --git a/buglist.cgi b/buglist.cgi index 31449de8b..35ee76310 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -860,6 +860,15 @@ if (!$order) { my @orderstrings = split(/,\s*/, $order); +# The bug status defined by a specific search is of type __foo__, but +# Search.pm converts it into a list of real bug statuses, which cannot +# be used when editing the specific search again. So we restore this +# parameter manually. +my $input_bug_status; +if ($params->param('query_format') eq 'specific') { + $input_bug_status = $params->param('bug_status'); +} + # Generate the basic SQL query that will be used to generate the bug list. my $search = new Bugzilla::Search('fields' => \@selectcolumns, 'params' => $params, @@ -1090,6 +1099,9 @@ if ($format->{'extension'} eq 'ics') { } } +# Restore the bug status used by the specific search. +$params->param('bug_status', $input_bug_status) if $input_bug_status; + # The list of query fields in URL query string format, used when creating # URLs to the same query results page with different parameters (such as # a different sort order or when taking some action on the set of query diff --git a/chart.cgi b/chart.cgi index d95441c58..3f82370d0 100755 --- a/chart.cgi +++ b/chart.cgi @@ -200,7 +200,7 @@ elsif ($action eq "delete") { $series->remove_from_db(); # Remove (sub)categories which no longer have any series. - foreach my $cat qw(category subcategory) { + foreach my $cat (qw(category subcategory)) { my $is_used = $dbh->selectrow_array("SELECT COUNT(*) FROM series WHERE $cat = ?", undef, $series->{"${cat}_id"}); if (!$is_used) { diff --git a/collectstats.pl b/collectstats.pl index d2c50133a..af487e2b7 100755 --- a/collectstats.pl +++ b/collectstats.pl @@ -49,9 +49,12 @@ use Bugzilla::Field; # in the regenerate mode). $| = 1; +my $datadir = bz_locations()->{'datadir'}; +my $graphsdir = bz_locations()->{'graphsdir'}; + # Tidy up after graphing module my $cwd = Cwd::getcwd(); -if (chdir("graphs")) { +if (chdir($graphsdir)) { unlink <./*.gif>; unlink <./*.png>; # chdir("..") doesn't work if graphs is a symlink, see bug 429378 @@ -68,8 +71,6 @@ if ($#ARGV >= 0 && $ARGV[0] eq "--regenerate") { $regenerate = 1; } -my $datadir = bz_locations()->{'datadir'}; - my @myproducts = map {$_->name} Bugzilla::Product->get_all; unshift(@myproducts, "-All-"); diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl index 32c8561a0..104151d85 100755 --- a/contrib/bz_webservice_demo.pl +++ b/contrib/bz_webservice_demo.pl @@ -210,7 +210,7 @@ if ($fetch_extension_info) { _die_on_fault($soapresult); my $extensions = $soapresult->result()->{extensions}; foreach my $extensionname (keys(%$extensions)) { - print "Extensionn '$extensionname' information\n"; + print "Extension '$extensionname' information\n"; my $extension = $extensions->{$extensionname}; foreach my $data (keys(%$extension)) { print ' ' . $data . ' => ' . $extension->{$data} . "\n"; diff --git a/docs/en/html/Bugzilla-Guide.html b/docs/en/html/Bugzilla-Guide.html index d4bc64005..80c9000d7 100644 --- a/docs/en/html/Bugzilla-Guide.html +++ b/docs/en/html/Bugzilla-Guide.html @@ -2,7 +2,7 @@ The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 ReleaseThe Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release

The Bugzilla Team

2010-08-05

2010-11-02

1.3. New Versions

This is the 3.6.2 version of The Bugzilla Guide. It is so named +> This is the 3.6.3 version of The Bugzilla Guide. It is so named to match the current version of Bugzilla.

  • Select "Add" in the bottom right corner. - text

    Select "Add" in the bottom right corner.

  • 3.8.5.1. Editing a Flag

    To edit a flag's properties, just click on the "Edit" - link next to the flag's description. That will take you to the same +> To edit a flag's properties, just click the flag's name. + That will take you to the same form as described below (Section 3.8.5.2

    Groups allow for separating bugs into logical divisions. - Groups are typically used to + Groups are typically used to isolate bugs that should only be seen by certain people. For example, a company might create a different group for each one of its customers or partners. Group permissions could be set so that each partner or customer would @@ -10868,7 +10864,7 @@ CLASS="section" >


    3.15.4. Assigning Group Controls to Products

    At first glance, negation seems redundant. Rather than searching for

    one could search for
    However, the search

    5.8.1. Autolinkification


    5.11.2.1. Creating Charts


    5.13.4. Saving Your Changes

    Example A-1. Examples of urlbase/cookiepath pairs for sharing login cookies

    Example A-2. Examples of urlbase/cookiepath pairs to restrict the login cookie

    Version 1.1, March 2000

    0-9, high ascii

    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    3.15.4. Assigning Group Controls to Products
  • object_before_create
  • object_before_delete
  • object_before_set +
  • object_end_of_create
  • object_end_of_create_validators
  • object_end_of_set
  • object_end_of_set_all @@ -223,8 +224,8 @@ name="bug_end_of_create"

    Params:

    -
    bug - The changed bug object, with all fields set to their updated values.
    +
    bug - The created bug object.
    +

    object_end_of_create

    + +

    Called at the end of "create" in Bugzilla::Object, after all other changes are made to the database. This occurs inside a database transaction.

    + +

    Params:

    + +
    +
    class
    + +
    +

    The name of the class that create was called on. You can check this like if ($class->isa('Some::Class')) in your code, to perform specific tasks for only certain classes.

    + +
    object
    + +
    +

    The created object.

    +
    +
    +

    object_end_of_create_validators

    diff --git a/docs/en/html/api/Bugzilla/WebService/User.html b/docs/en/html/api/Bugzilla/WebService/User.html index ab0affb0d..21098657a 100644 --- a/docs/en/html/api/Bugzilla/WebService/User.html +++ b/docs/en/html/api/Bugzilla/WebService/User.html @@ -120,6 +120,13 @@ or the password is wrong.

    The account has been disabled. A reason may be specified with the error.

    +
    305 (New Password Required)
    + +
    +

    The current password is correct, +but the user is asked to change his password.

    +
    50 (Param Required)
    diff --git a/docs/en/html/api/index.html b/docs/en/html/api/index.html index 8e92dba4c..76ef495e2 100644 --- a/docs/en/html/api/index.html +++ b/docs/en/html/api/index.html @@ -2,13 +2,13 @@ - Bugzilla 3.6.2 API Documentation + Bugzilla 3.6.3 API Documentation -

    Bugzilla 3.6.2 API Documentation

    +

    Bugzilla 3.6.3 API Documentation

    Extensions
    diff --git a/docs/en/html/attachments.html b/docs/en/html/attachments.html index ee731ccf8..9a5408ed3 100644 --- a/docs/en/html/attachments.html +++ b/docs/en/html/attachments.html @@ -7,7 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.79">
  • 3.8.5.1. Editing a Flag

    To edit a flag's properties, just click on the "Edit" - link next to the flag's description. That will take you to the same +> To edit a flag's properties, just click the flag's name. + That will take you to the same form as described below (Section 3.8.5.2

    Version 1.1, March 2000

    0-9, high ascii

    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release

    Groups allow for separating bugs into logical divisions. - Groups are typically used to + Groups are typically used to isolate bugs that should only be seen by certain people. For example, a company might create a different group for each one of its customers or partners. Group permissions could be set so that each partner or customer would @@ -506,7 +506,7 @@ CLASS="section" >

    3.15.4. Assigning Group Controls to Products

    5.8.1. Autolinkification

    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 ReleaseThe Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release

    The Bugzilla Team

    2010-08-05

    2010-11-02

  • Select "Add" in the bottom right corner. - text

    Select "Add" in the bottom right corner.

  • 1.3. New Versions

    This is the 3.6.2 version of The Bugzilla Guide. It is so named +> This is the 3.6.3 version of The Bugzilla Guide. It is so named to match the current version of Bugzilla.

    At first glance, negation seems redundant. Rather than searching for
    one could search for
    However, the search

    5.11.2.1. Creating Charts

    Example A-1. Examples of urlbase/cookiepath pairs for sharing login cookies

    Example A-2. Examples of urlbase/cookiepath pairs to restrict the login cookie

    5.8.1. Autolinkification
    5.13.4. Saving Your Changes

    5.13.4. Saving Your Changes

    - + - + diff --git a/docs/en/xml/administration.xml b/docs/en/xml/administration.xml index 926d1f8a3..ae5c32158 100644 --- a/docs/en/xml/administration.xml +++ b/docs/en/xml/administration.xml @@ -1833,8 +1833,7 @@ ReadOnly: ENTRY, NA/NA, CANEDIT - Select "Add" in the bottom right corner. - text + Select "Add" in the bottom right corner. @@ -2068,8 +2067,8 @@ ReadOnly: ENTRY, NA/NA, CANEDIT

    Editing a Flag - To edit a flag's properties, just click on the Edit - link next to the flag's description. That will take you to the same + To edit a flag's properties, just click the flag's name. + That will take you to the same form as described below ().
    @@ -2641,7 +2640,7 @@ ReadOnly: ENTRY, NA/NA, CANEDIT Groups allow for separating bugs into logical divisions. - Groups are typically used to + Groups are typically used to isolate bugs that should only be seen by certain people. For example, a company might create a different group for each one of its customers or partners. Group permissions could be set so that each partner or customer would diff --git a/email_in.pl b/email_in.pl index fa1c9584b..cd4bae9db 100755 --- a/email_in.pl +++ b/email_in.pl @@ -42,6 +42,7 @@ use Email::MIME::Attachment::Stripper; use Getopt::Long qw(:config bundling); use Pod::Usage; use Encode; +use Scalar::Util qw(blessed); use Bugzilla; use Bugzilla::Attachment; @@ -430,7 +431,8 @@ sub die_handler { # In Template-Toolkit, [% RETURN %] is implemented as a call to "die". # But of course, we really don't want to actually *die* just because # the user-error or code-error template ended. So we don't really die. - return if ref $msg && $msg->isa('Template::Exception') && $msg->type eq 'return'; + return if blessed($msg) && $msg->isa('Template::Exception') + && $msg->type eq 'return'; # If this is inside an eval, then we should just act like...we're # in an eval (instead of printing the error and exiting). diff --git a/extensions/Example/Extension.pm b/extensions/Example/Extension.pm index d8e4228c0..60096692e 100644 --- a/extensions/Example/Extension.pm +++ b/extensions/Example/Extension.pm @@ -359,6 +359,15 @@ sub object_before_set { } } +sub object_end_of_create { + my ($self, $args) = @_; + + my $class = $args->{'class'}; + my $object = $args->{'object'}; + + warn "Created a new $class object!"; +} + sub object_end_of_create_validators { my ($self, $args) = @_; diff --git a/importxml.pl b/importxml.pl index 79ebf4095..d0f0d78ae 100755 --- a/importxml.pl +++ b/importxml.pl @@ -935,7 +935,7 @@ sub process_bug { $initial_status = $bug_statuses[0]->name; } else { - @bug_statuses = @{Bugzilla::Status->get_all()}; + @bug_statuses = Bugzilla::Status->get_all(); # Exclude UNCO and inactive bug statuses. @bug_statuses = grep { $_->is_active && $_->name ne 'UNCONFIRMED'} @bug_statuses; my @open_statuses = grep { $_->is_open } @bug_statuses; diff --git a/query.cgi b/query.cgi index e470c6f81..2c9fef8fb 100755 --- a/query.cgi +++ b/query.cgi @@ -143,10 +143,7 @@ sub PrefillForm { for my $field (Bugzilla->active_custom_fields) { push @list, $field->name; - if ($field->type == FIELD_TYPE_FREETEXT || $field->type == FIELD_TYPE_TEXTAREA) - { - push @list, $field->name . '_type'; - } + push @list, $field->name . '_type'; } foreach my $name (@list) { diff --git a/reports.cgi b/reports.cgi index 03ac8776c..c6e21c09f 100755 --- a/reports.cgi +++ b/reports.cgi @@ -45,31 +45,28 @@ use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Status; +use File::Basename; +use Digest::MD5 qw(md5_hex); + # If we're using bug groups for products, we should apply those restrictions # to viewing reports, as well. Time to check the login in that case. my $user = Bugzilla->login(); +my $cgi = Bugzilla->cgi; +my $template = Bugzilla->template; +my $vars = {}; if (!Bugzilla->feature('old_charts')) { ThrowCodeError('feature_disabled', { feature => 'old_charts' }); } my $dir = bz_locations()->{'datadir'} . "/mining"; -my $graph_url = 'graphs'; -my $graph_dir = bz_locations()->{'libpath'} . '/' .$graph_url; +my $graph_dir = bz_locations()->{'graphsdir'}; +my $graph_url = basename($graph_dir); +my $product_name = $cgi->param('product') || ''; Bugzilla->switch_to_shadow_db(); -my $cgi = Bugzilla->cgi; -my $template = Bugzilla->template; -my $vars = {}; - -# We only want those products that the user has permissions for. -my @myproducts; -push( @myproducts, "-All-"); -# Extract product names from objects and add them to the list. -push( @myproducts, map { $_->name } @{$user->get_selectable_products} ); - -if (! defined $cgi->param('product')) { +if (!$product_name) { # Can we do bug charts? (-d $dir && -d $graph_dir) || ThrowCodeError('chart_dir_nonexistent', @@ -87,51 +84,60 @@ if (! defined $cgi->param('product')) { push(@datasets, $datasets); } + # We only want those products that the user has permissions for. + my @myproducts = ('-All-'); + # Extract product names from objects and add them to the list. + push( @myproducts, map { $_->name } @{$user->get_selectable_products} ); + $vars->{'datasets'} = \@datasets; $vars->{'products'} = \@myproducts; - - $cgi->send_header(); - - $template->process('reports/old-charts.html.tmpl', $vars) - || ThrowTemplateError($template->error()); - exit; } else { - my $product = $cgi->param('product'); - # For security and correctness, validate the value of the "product" form variable. # Valid values are those products for which the user has permissions which appear # in the "product" drop-down menu on the report generation form. - grep($_ eq $product, @myproducts) - || ThrowUserError("invalid_product_name", {product => $product}); + my ($product) = grep { $_->name eq $product_name } @{$user->get_selectable_products}; + ($product || $product_name eq '-All-') + || ThrowUserError('invalid_product_name', {product => $product_name}); - # We've checked that the product exists, and that the user can see it - # This means that is OK to detaint - trick_taint($product); + # Product names can change over time. Their ID cannot; so use the ID + # to generate the filename. + my $prod_id = $product ? $product->id : 0; - defined($cgi->param('datasets')) || ThrowUserError('missing_datasets'); + # Make sure there is something to plot. + my @datasets = $cgi->param('datasets'); + scalar(@datasets) || ThrowUserError('missing_datasets'); - my $datasets = join('', $cgi->param('datasets')); - - my $type = chart_image_type(); - my $data_file = daily_stats_filename($product); - my $image_file = chart_image_name($data_file, $type, $datasets); - my $url_image = correct_urlbase() . "$graph_url/$image_file"; - - if (! -e "$graph_dir/$image_file") { - generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type, - $product, $datasets); + if (grep { $_ !~ /^[A-Za-z0-9:_-]+$/ } @datasets) { + ThrowUserError('invalid_datasets', {'datasets' => \@datasets}); } - $vars->{'url_image'} = $url_image; + # Filenames must not be guessable as they can point to products + # you are not allowed to see. Also, different projects can have + # the same product names. + my $key = Bugzilla->localconfig->{'site_wide_secret'}; + my $project = bz_locations()->{'project'} || ''; + my $image_file = join(':', ($key, $project, $prod_id, @datasets)); + # Wide characters cause md5_hex() to die. + if (Bugzilla->params->{'utf8'}) { + utf8::encode($image_file) if utf8::is_utf8($image_file); + } + my $type = chart_image_type(); + $image_file = md5_hex($image_file) . ".$type"; + trick_taint($image_file); + + if (! -e "$graph_dir/$image_file") { + generate_chart($dir, "$graph_dir/$image_file", $type, $product, \@datasets); + } + + $vars->{'url_image'} = "$graph_url/$image_file"; $cgi->send_header(-Content_Disposition=>'inline; filename=bugzilla_report.html'); - - $template->process('reports/old-charts.html.tmpl', $vars) - || ThrowTemplateError($template->error()); - exit; } +$template->process('reports/old-charts.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + ##################### # Subroutines # ##################### @@ -140,9 +146,8 @@ sub get_data { my $dir = shift; my @datasets; - my $datafile = daily_stats_filename('-All-'); - open(DATA, '<', "$dir/$datafile") - || ThrowCodeError('chart_file_open_fail', {filename => "$dir/$datafile"}); + open(DATA, '<', "$dir/-All-") + || ThrowCodeError('chart_file_open_fail', {filename => "$dir/-All-"}); while () { if (/^# fields?: (.+)\s*$/) { @@ -154,12 +159,6 @@ sub get_data { return @datasets; } -sub daily_stats_filename { - my ($prodname) = @_; - $prodname =~ s/\//-/gs; - return $prodname; -} - sub chart_image_type { # what chart type should we be generating? my $testimg = Chart::Lines->new(2,2); @@ -169,32 +168,12 @@ sub chart_image_type { return $type; } -sub chart_image_name { - my ($data_file, $type, $datasets) = @_; - - # This routine generates a filename from the requested fields. The problem - # is that we have to check the safety of doing this. We can't just require - # that the fields exist, because what stats were collected could change - # over time (eg by changing the resolutions available) - # Instead, just require that each field name consists only of letters, - # numbers, underscores and hyphens. - - if ($datasets !~ m/^[A-Za-z0-9:_-]+$/) { - ThrowUserError('invalid_datasets', {'datasets' => $datasets}); - } - - # Since we pass the tests, consider it OK - trick_taint($datasets); - - # Cache charts by generating a unique filename based on what they - # show. Charts should be deleted by collectstats.pl nightly. - my $id = join ("_", split (":", $datasets)); - - return "${data_file}_${id}.$type"; -} - sub generate_chart { - my ($data_file, $image_file, $type, $product, $datasets) = @_; + my ($dir, $image_file, $type, $product, $datasets) = @_; + $product = $product ? $product->name : '-All-'; + my $data_file = $product; + $data_file =~ s/\//-/gs; + $data_file = $dir . '/' . $data_file; if (! open FILE, $data_file) { if ($product eq '-All-') { @@ -205,7 +184,7 @@ sub generate_chart { my @fields; my @labels = qw(DATE); - my %datasets = map { $_ => 1 } split /:/, $datasets; + my %datasets = map { $_ => 1 } @$datasets; my %data = (); while () { diff --git a/skins/standard/global.css b/skins/standard/global.css index 93cd308aa..d4f3a4bc2 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -358,7 +358,7 @@ div#docslinks { display: none !important; } -span.quote { +.bz_comment_text span.quote { color: #65379c; /* Make quoted text not wrap. */ white-space: pre; diff --git a/skins/standard/show_bug.css b/skins/standard/show_bug.css index ad1d6a0a0..ee5746ed3 100644 --- a/skins/standard/show_bug.css +++ b/skins/standard/show_bug.css @@ -138,6 +138,10 @@ table#flags { white-space: nowrap; } +.bz_bug .bz_alias_short_desc_container { + width: inherit; +} + #comment_textarea { width: 50em; font-size: medium; font-family: monospace; } #cf_sprint { max-width: 25em; min-width: 0; } diff --git a/t/012throwables.t b/t/012throwables.t index 4be02c58a..3738ad524 100644 --- a/t/012throwables.t +++ b/t/012throwables.t @@ -117,7 +117,7 @@ foreach my $file (keys %test_modules) { # Bugzilla/Error.pm) $lineno++; if ($line =~ -/^[^#]*(Throw(Code|User)Error|error\s+=>)\s*\(?\s*["'](.*?)['"]/) { +/^[^#]*\b(Throw(Code|User)Error|(user_)?error\s+=>)\s*\(?\s*["'](.*?)['"]/) { my $errtype; # If it's a normal ThrowCode/UserError if ($2) { @@ -125,9 +125,9 @@ foreach my $file (keys %test_modules) { } # If it's an AUTH_ERROR tag else { - $errtype = 'code'; + $errtype = $3 ? 'user' : 'code'; } - my $errtag = $3; + my $errtag = $4; push @{$Errors{$errtype}{$errtag}{used_in}{$file}}, $lineno; } } diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl index a2ded34ea..77bc27f6d 100644 --- a/template/en/default/account/auth/login-small.html.tmpl +++ b/template/en/default/account/auth/login-small.html.tmpl @@ -32,7 +32,12 @@
  • | - Log In
  • | - Forgot Password diff --git a/template/en/default/account/email/confirm-new.html.tmpl b/template/en/default/account/email/confirm-new.html.tmpl index ed0ff3405..36bd52d09 100644 --- a/template/en/default/account/email/confirm-new.html.tmpl +++ b/template/en/default/account/email/confirm-new.html.tmpl @@ -24,11 +24,11 @@ title = title onload = "document.forms['confirm_account_form'].realname.focus();" %] -
    +

    To create your account, you must enter a password in the form below. Your email address and Real Name (if provided) will be shown with changes you make. -

    +

    @@ -44,7 +44,10 @@
  • - + diff --git a/template/en/default/account/password/set-forgotten-password.html.tmpl b/template/en/default/account/password/set-forgotten-password.html.tmpl index ca134a486..a2ae517c8 100644 --- a/template/en/default/account/password/set-forgotten-password.html.tmpl +++ b/template/en/default/account/password/set-forgotten-password.html.tmpl @@ -33,6 +33,7 @@ diff --git a/template/en/default/admin/sudo.html.tmpl b/template/en/default/admin/sudo.html.tmpl index 680bcfbb3..283eebe15 100644 --- a/template/en/default/admin/sudo.html.tmpl +++ b/template/en/default/admin/sudo.html.tmpl @@ -83,8 +83,7 @@ password: - +
    This is done for two reasons. First of all, it is done to reduce the chances of someone doing large amounts of damage using your diff --git a/template/en/default/admin/table.html.tmpl b/template/en/default/admin/table.html.tmpl index 45fa1168c..ca3d1bf25 100644 --- a/template/en/default/admin/table.html.tmpl +++ b/template/en/default/admin/table.html.tmpl @@ -145,7 +145,7 @@ [% link_uri = contentlink %] [% WHILE link_uri.search('%%(.+?)%%')%] [% FOREACH m = link_uri.match('%%(.+?)%%') %] - [% IF row.$m %] + [% IF row.$m.defined %] [% replacement_value = FILTER url_quote; row.$m; END %] [% ELSE %] [% replacement_value = "" %] diff --git a/template/en/default/admin/users/userdata.html.tmpl b/template/en/default/admin/users/userdata.html.tmpl index f23aa1b85..9b182fa14 100644 --- a/template/en/default/admin/users/userdata.html.tmpl +++ b/template/en/default/admin/users/userdata.html.tmpl @@ -61,9 +61,8 @@ diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl index 92357df5a..0079344ed 100644 --- a/template/en/default/pages/release-notes.html.tmpl +++ b/template/en/default/pages/release-notes.html.tmpl @@ -61,6 +61,50 @@

    Updates in this 3.6.x Release

    +

    3.6.3

    + +

    This release fixes various important security issues. See the + Security Advisory + for details.

    + +

    In addition, the following important fixes/changes have been made in + this release:

    + +
      +
    • It is no longer possible to get a mid-air collision again after + selecting "Submit only my comment" on the mid-air collision page. + ([% terms.Bug %] 591218) +
    • +
    • Saving a search with either of the deadline fields set to "Now" would + cause that deadline field to be removed from the saved search. + ([% terms.Bug %] 590144) +
    • +
    • Searching for [% terms.bugs %] "with at least X votes" was instead + returning [% terms.bugs %] with exactly that many votes. + ([% terms.Bug %] 584414) +
    • +
    • Typing something like "P1-5" in the quicksearch box should have + been searching the [% field_descs.priority FILTER html %] field, + but it was not. + ([% terms.Bug %] 585028) +
    • +
    • Users who had passwords less than 6 characters long couldn't log in. + Such users could only exist before 3.6, so it looked like after upgrading + to 3.6, certain users couldn't log in. + ([% terms.Bug %] 575947) +
    • +
    • Loading config.cgi?ctype=rdf should + now be faster, particularly on installations that have many flags. + ([% terms.Bug %] 553266 + and [% terms.Bug %] 605693) +
    • +
    • Non-english templates were not being precompiled by checksetup.pl, + leading to reduced performance for localized [% terms.Bugzilla %] + installations. + ([% terms.Bug %] 605425) +
    • +
    +

    3.6.2

    This release fixes various security issues. See the @@ -76,7 +120,7 @@ sometimes occur. ([% terms.Bug %] 521416) -

  • Email notifications where missing the dates that comments were made. +
  • Email notifications were missing the dates that comments were made. ([% terms.Bug %] 578003)
  • Putting a phrase in quotes in the Quicksearch box now works properly, diff --git a/template/en/default/reports/old-charts.html.tmpl b/template/en/default/reports/old-charts.html.tmpl index ca3ba6c7d..4bdc0cffa 100644 --- a/template/en/default/reports/old-charts.html.tmpl +++ b/template/en/default/reports/old-charts.html.tmpl @@ -51,7 +51,7 @@ [%# We cannot use translated statuses and resolutions from field-descs.none.html # because old charts do not distinguish statuses from resolutions. %] [% FOREACH dataset = datasets %] - [% END %] diff --git a/template/en/default/setup/strings.txt.pl b/template/en/default/setup/strings.txt.pl index eec0bd90e..9f8744ec4 100644 --- a/template/en/default/setup/strings.txt.pl +++ b/template/en/default/setup/strings.txt.pl @@ -130,6 +130,7 @@ EOT module_not_found => "not found", module_ok => 'ok', module_unknown_version => "found unknown version", + no_such_module => "There is no Perl module on CPAN named ##module##.", ppm_repo_add => <
  • The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    The Bugzilla Guide - 3.6.2 +>The Bugzilla Guide - 3.6.3 Release
    : + + (minimum [% constants.USER_PASSWORD_MIN_LENGTH FILTER none %] characters) +
    :New Password: + (minimum [% constants.USER_PASSWORD_MIN_LENGTH FILTER none %] characters)
    - + [% IF editform %]
    (Enter new password to change.) [% END %] diff --git a/template/en/default/config.rdf.tmpl b/template/en/default/config.rdf.tmpl index 97d4f23c1..16b8edbc7 100644 --- a/template/en/default/config.rdf.tmpl +++ b/template/en/default/config.rdf.tmpl @@ -19,6 +19,10 @@ # Frédéric Buclin #%] +[%# The url to the installation is going to be displayed many times. + # So we cache it here for better performance. + %] +[% escaped_urlbase = BLOCK %][% urlbase FILTER xml %][% END %] @@ -27,7 +31,7 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:bz="http://www.bugzilla.org/rdf#"> - + [% constants.BUGZILLA_VERSION FILTER html %] [% Param('maintainer') FILTER html %] @@ -122,13 +126,13 @@ [% FOREACH product = products %]
  • - + [% product.name FILTER html %] [% FOREACH component = product.components %] -
  • [% END %] @@ -137,7 +141,7 @@ [% FOREACH version = product.versions %] -
  • +
  • [% END %] @@ -146,7 +150,7 @@ [% FOREACH milestone = product.milestones %] -
  • +
  • [% END %] @@ -164,7 +168,7 @@ [% FOREACH product = products %] [% FOREACH component = product.components %]
  • - [% component.name FILTER html %] [% IF show_flags %] @@ -174,7 +178,7 @@ [% FOREACH flag_type = flag_types %] [% NEXT UNLESS flag_type.is_active %] [% all_visible_flag_types.${flag_type.id} = flag_type %] -
  • [% END %] @@ -192,7 +196,7 @@ [% FOREACH product = products %] [% FOREACH version = product.versions %]
  • - + [% version.name FILTER html %]
  • @@ -207,7 +211,7 @@ [% FOREACH product = products %] [% FOREACH milestone = product.milestones %]
  • - + [% milestone.name FILTER html %]
  • @@ -222,7 +226,7 @@ [% FOREACH flag_type = all_visible_flag_types.values.sort('name') %]
  • - [% flag_type.id FILTER html %] [% flag_type.name FILTER html %] @@ -247,7 +251,7 @@ [% PROCESS "global/field-descs.none.tmpl" %] [% FOREACH item = field %]
  • - + [% item.name FILTER html %] [% (field_descs.${item.name} OR item.description) FILTER html %] [%-# These values are meaningful for custom fields only. %] diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index 2c096df73..cc4d09d3e 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -528,4 +528,8 @@ 'group.id', ], +'config.rdf.tmpl' => [ + 'escaped_urlbase', +], + ); diff --git a/template/en/default/global/footer.html.tmpl b/template/en/default/global/footer.html.tmpl index f56f9eaab..8ada01f22 100644 --- a/template/en/default/global/footer.html.tmpl +++ b/template/en/default/global/footer.html.tmpl @@ -43,5 +43,7 @@ [% END %] +[% Hook.process("end") %] + diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index e66f7a588..f52a317b6 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -230,9 +230,17 @@ [% url FILTER html %] is not a valid URL to [% terms.abug %]. [% IF reason == 'http' %] URLs must start with "http" or "https". + [% ELSIF reason == 'path_only' %] + You must specify a full URL. [% ELSIF reason == 'show_bug' %] - [%+ terms.Bug %] URLs should point to show_bug.cgi - in a [% terms.Bugzilla %] installation. + [%+ field_descs.see_also FILTER html %] URLs should point to one of: +
      +
    • show_bug.cgi in a [% terms.Bugzilla %] + installation.
    • +
    • A b[% %]ug on launchpad.net
    • +
    • An issue on code.google.com.
    • +
    • A b[% %]ug on b[% %]ugs.debian.org.
    • +
    [% ELSIF reason == 'id' %] There is no valid [% terms.bug %] id in that URL. [% END %] @@ -563,7 +571,7 @@ [% ELSIF error == "file_too_large" %] [% title = "File Too Large" %] The file you are trying to attach is [% filesize FILTER html %] - kilobytes (KB) in size. Non-patch attachments cannot be more than + kilobytes (KB) in size. Attachments cannot be more than [%+ Param('maxattachmentsize') %] KB.
    We recommend that you store your attachment elsewhere [% IF Param("allow_attach_url") %] @@ -902,7 +910,7 @@ [% ELSIF error == "invalid_datasets" %] [% title = "Invalid Datasets" %] - Invalid datasets [% datasets FILTER html %]. Only digits, + Invalid datasets [% datasets.join(":") FILTER html %]. Only digits, letters and colons are allowed. [% ELSIF error == "invalid_format" %] @@ -1284,6 +1292,14 @@ [% title = "Passwords Don't Match" %] The two passwords you entered did not match. + [% ELSIF error == "password_current_too_short" %] + [% title = "New Password Required" %] + Your password is currently less than + [%+ constants.USER_PASSWORD_MIN_LENGTH FILTER html %] characters long, + which is the new minimum length required for passwords. + You must + request a new password in order to log in again. + [% ELSIF error == "password_too_short" %] [% title = "Password Too Short" %] The password must be at least diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl index 89ff327a9..f2513cd6d 100644 --- a/template/en/default/list/table.html.tmpl +++ b/template/en/default/list/table.html.tmpl @@ -74,6 +74,8 @@ [% PROCESS bug/time.html.tmpl %] +[% Hook.process("before_table") %] + [%############################################################################%] [%# Table Header #%] [%############################################################################%] @@ -164,8 +166,6 @@ [%# Bug Table #%] [%############################################################################%] -[% Hook.process("before_table") %] - [% tableheader %]