diff options
-rw-r--r-- | Bugzilla/Config.pm | 5 | ||||
-rw-r--r-- | Bugzilla/Config/Query.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Constants.pm | 7 | ||||
-rw-r--r-- | Bugzilla/Install/Filesystem.pm | 27 | ||||
-rw-r--r-- | Bugzilla/Search.pm | 5 | ||||
-rw-r--r-- | Bugzilla/Update.pm | 26 | ||||
-rwxr-xr-x | buglist.cgi | 2 | ||||
-rwxr-xr-x | collectstats.pl | 30 | ||||
-rw-r--r-- | template/en/default/admin/params/query.html.tmpl | 11 | ||||
-rw-r--r-- | template/en/default/global/messages.html.tmpl | 4 | ||||
-rw-r--r-- | template/en/default/index.html.tmpl | 16 | ||||
-rw-r--r-- | template/en/default/search/search-specific.html.tmpl | 2 | ||||
-rwxr-xr-x | whine.pl | 10 |
13 files changed, 105 insertions, 42 deletions
diff --git a/Bugzilla/Config.pm b/Bugzilla/Config.pm index c247a072a..990fd8dd2 100644 --- a/Bugzilla/Config.pm +++ b/Bugzilla/Config.pm @@ -193,6 +193,11 @@ sub update_params { $new_params{'ssl_redirect'} = 1; } + # "specific_search_allow_empty_words" has been renamed to "search_allow_no_criteria". + if (exists $param->{'specific_search_allow_empty_words'}) { + $new_params{'search_allow_no_criteria'} = $param->{'specific_search_allow_empty_words'}; + } + # --- DEFAULTS FOR NEW PARAMS --- _load_params unless %params; diff --git a/Bugzilla/Config/Query.pm b/Bugzilla/Config/Query.pm index 17a74998e..4038c13ef 100644 --- a/Bugzilla/Config/Query.pm +++ b/Bugzilla/Config/Query.pm @@ -68,7 +68,7 @@ sub get_param_list { }, { - name => 'specific_search_allow_empty_words', + name => 'search_allow_no_criteria', type => 'b', default => 1 }, diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 62836d8cc..43b36547f 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -40,6 +40,9 @@ use Memoize; @Bugzilla::Constants::EXPORT = qw( BUGZILLA_VERSION + REMOTE_FILE + LOCAL_FILE + bz_locations IS_NULL @@ -201,6 +204,10 @@ use Memoize; # Bugzilla version use constant BUGZILLA_VERSION => "4.1.3+"; +# Location of the remote and local XML files to track new releases. +use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; +use constant LOCAL_FILE => 'bugzilla-update.xml'; # Relative to datadir. + # 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, diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index e6783bbee..c3f103aaa 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -46,6 +46,7 @@ our @EXPORT = qw( update_filesystem create_htaccess fix_all_file_permissions + fix_dir_permissions fix_file_permissions ); @@ -651,6 +652,26 @@ sub _update_old_charts { } } +sub fix_dir_permissions { + my ($dir) = @_; + return if ON_WINDOWS; + # Note that _get_owner_and_group is always silent here. + my ($owner_id, $group_id) = _get_owner_and_group(); + + my $perms; + my $fs = FILESYSTEM(); + if ($perms = $fs->{recurse_dirs}->{$dir}) { + _fix_perms_recursively($dir, $owner_id, $group_id, $perms); + } + elsif ($perms = $fs->{all_dirs}->{$dir}) { + _fix_perms($dir, $owner_id, $group_id, $perms); + } + else { + # Do nothing. We know nothing about this directory. + warn "Unknown directory $dir"; + } +} + sub fix_file_permissions { my ($file) = @_; return if ON_WINDOWS; @@ -849,6 +870,12 @@ Params: C<$output> - C<true> if you want this function to print Returns: nothing +=item C<fix_dir_permissions> + +Given the name of a directory, its permissions will be fixed according to +how they are supposed to be set in Bugzilla's current configuration. +If it fails to set the permissions, a warning will be printed to STDERR. + =item C<fix_file_permissions> Given the name of a file, its permissions will be fixed according to diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index a1378e540..fdc0e2991 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -1168,6 +1168,11 @@ sub _sql_where { if ($clause_sql) { $where .= "\n AND " . $clause_sql; } + elsif (!Bugzilla->params->{'search_allow_no_criteria'} + && !$self->{allow_unlimited}) + { + ThrowUserError('buglist_parameters_required'); + } return $where; } diff --git a/Bugzilla/Update.pm b/Bugzilla/Update.pm index a94fd167d..c9942a4f0 100644 --- a/Bugzilla/Update.pm +++ b/Bugzilla/Update.pm @@ -20,8 +20,6 @@ use strict; use Bugzilla::Constants; -use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; -use constant LOCAL_FILE => "/bugzilla-update.xml"; # Relative to datadir. use constant TIME_INTERVAL => 86400; # Default is one day, in seconds. use constant TIMEOUT => 5; # Number of seconds before timeout. @@ -30,26 +28,25 @@ sub get_notifications { return if !Bugzilla->feature('updates'); return if (Bugzilla->params->{'upgrade_notification'} eq 'disabled'); - my $local_file = bz_locations()->{'datadir'} . LOCAL_FILE; + my $local_file = bz_locations()->{'datadir'} . '/' . LOCAL_FILE; # Update the local XML file if this one doesn't exist or if # the last modification time (stat[9]) is older than TIME_INTERVAL. if (!-e $local_file || (time() - (stat($local_file))[9] > TIME_INTERVAL)) { unlink $local_file; # Make sure the old copy is away. - if (-e $local_file) { - return { 'error' => 'no_update', xml_file => $local_file }; - } + return { 'error' => 'no_update' } if (-e $local_file); + my $error = _synchronize_data(); # If an error is returned, leave now. return $error if $error; } # If we cannot access the local XML file, ignore it. - return {'error' => 'no_access', 'xml_file' => $local_file} unless (-r $local_file); + return { 'error' => 'no_access' } unless (-r $local_file); my $twig = XML::Twig->new(); $twig->safe_parsefile($local_file); # If the XML file is invalid, return. - return {'error' => 'corrupted', 'xml_file' => $local_file} if $@; + return { 'error' => 'corrupted' } if $@; my $root = $twig->root; my @releases; @@ -119,7 +116,7 @@ sub get_notifications { } sub _synchronize_data { - my $local_file = bz_locations()->{'datadir'} . LOCAL_FILE; + my $local_file = bz_locations()->{'datadir'} . '/' . LOCAL_FILE; my $ua = LWP::UserAgent->new(); $ua->timeout(TIMEOUT); @@ -133,7 +130,7 @@ sub _synchronize_data { else { $ua->env_proxy; } - $ua->mirror(REMOTE_FILE, $local_file); + my $response = eval { $ua->mirror(REMOTE_FILE, $local_file) }; # $ua->mirror() forces the modification time of the local XML file # to match the modification time of the remote one. @@ -144,11 +141,14 @@ sub _synchronize_data { # Try to alter its last modification time. my $can_alter = utime(undef, undef, $local_file); # This error should never happen. - $can_alter || return {'error' => 'no_update', 'xml_file' => $local_file}; + $can_alter || return { 'error' => 'no_update' }; } - else { + elsif ($response && $response->is_error) { # We have been unable to download the file. - return {'error' => 'cannot_download', 'xml_file' => $local_file}; + return { 'error' => 'cannot_download', 'reason' => $response->status_line }; + } + else { + return { 'error' => 'no_write', 'reason' => $@ }; } # Everything went well. diff --git a/buglist.cgi b/buglist.cgi index bf8b443e6..85a8ae760 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -82,7 +82,7 @@ if (defined($searchstring)) { # If configured to not allow empty words, reject empty searches from the # Find a Specific Bug search form, including words being a single or # several consecutive whitespaces only. -if (!Bugzilla->params->{'specific_search_allow_empty_words'} +if (!Bugzilla->params->{'search_allow_no_criteria'} && defined($cgi->param('content')) && $cgi->param('content') =~ /^\s*$/) { ThrowUserError("buglist_parameters_required"); diff --git a/collectstats.pl b/collectstats.pl index 26bead6ab..1487e5a72 100755 --- a/collectstats.pl +++ b/collectstats.pl @@ -41,6 +41,7 @@ use Bugzilla::Search; use Bugzilla::User; use Bugzilla::Product; use Bugzilla::Field; +use Bugzilla::Install::Filesystem qw(fix_dir_permissions); my %switch; GetOptions(\%switch, 'help|h', 'regenerate'); @@ -139,32 +140,28 @@ my $tstart = time; my @myproducts = Bugzilla::Product->get_all; unshift(@myproducts, "-All-"); -foreach (@myproducts) { - my $dir = "$datadir/mining"; - - &check_data_dir ($dir); +my $dir = "$datadir/mining"; +if (!-d $dir) { + mkdir $dir or die "mkdir $dir failed: $!"; + fix_dir_permissions($dir); +} +foreach (@myproducts) { if ($switch{'regenerate'}) { regenerate_stats($dir, $_, \%bug_resolution, \%bug_status, \%removed); } else { &collect_stats($dir, $_); } } +# Fix permissions for all files in mining/. +fix_dir_permissions($dir); + my $tend = time; # Uncomment the following line for performance testing. #print "Total time taken " . delta_time($tstart, $tend) . "\n"; CollectSeriesData(); -sub check_data_dir { - my $dir = shift; - - if (! -d $dir) { - mkdir $dir, 0755; - chmod 0755, $dir; - } -} - sub collect_stats { my $dir = shift; my $product = shift; @@ -250,7 +247,6 @@ FIN } print DATA (join '|', @row) . "\n"; close DATA; - chmod 0644, $file; } sub get_old_data { @@ -406,14 +402,13 @@ FIN foreach (@resolutions) { print DATA "|$bugcount{$_}"; } print DATA "\n"; } - + # Finish up output feedback for this product. my $tend = time; print "\rRegenerating $product \[100.0\%] - " . delta_time($tstart, $tend) . "\n"; - + close DATA; - chmod 0640, $file; } } @@ -507,6 +502,7 @@ sub CollectSeriesData { eval { my $search = new Bugzilla::Search('params' => scalar $cgi->Vars, 'fields' => ["bug_id"], + 'allow_unlimited' => 1, 'user' => $user); my $sql = $search->sql; $data = $shadow_dbh->selectall_arrayref($sql); diff --git a/template/en/default/admin/params/query.html.tmpl b/template/en/default/admin/params/query.html.tmpl index d8f5f0c42..255c75a6b 100644 --- a/template/en/default/admin/params/query.html.tmpl +++ b/template/en/default/admin/params/query.html.tmpl @@ -51,9 +51,14 @@ "access the advanced query page. It's in URL parameter " _ "format, which makes it hard to read. Sorry!", - specific_search_allow_empty_words => - "Whether to allow a search on the 'Simple Search' page with an empty" - _ " 'Words' field.", + search_allow_no_criteria => + "Unless the code explicitly allows all $terms.bugs to be returned, this " _ + "parameter permits to block the execution of queries with no criteria. " _ + "When turned off, a query must have some criteria specified to limit " _ + "the number of $terms.bugs returned to the user. When turned on, a user " _ + "is allowed to run a query with no criteria and get all $terms.bugs he can " _ + "see in his list. Turning this parameter on is not recommended on large " _ + "installations.", default_search_limit => "By default, $terms.Bugzilla limits searches done in the web" diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index 6e24198dd..2567d4a7a 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -924,6 +924,10 @@ No changes made to version <em>[% version.name FILTER html %]</em>. [% END %] + [% ELSIF message_tag == "whine_query_failed" %] + The query '[% query_name FILTER html %]' from [% author.login FILTER html %] + failed: [% reason FILTER html %] + [% ELSIF message_tag == "workflow_updated" %] The workflow has been updated. [% END %] diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl index b1370261f..98648e25e 100644 --- a/template/en/default/index.html.tmpl +++ b/template/en/default/index.html.tmpl @@ -92,18 +92,24 @@ YAHOO.util.Event.onDOMReady(onLoadActions); You can configure this notification from the <a href="editparams.cgi?section=general#upgrade_notification_desc">Parameters</a> page.</p> [% ELSIF release.error == "cannot_download" %] - <p>The local XML file '[% release.xml_file FILTER html %]' cannot be created. - Please make sure the web server can write in this directory and that you can access + <p>The remote file <a href="[% constants.REMOTE_FILE FILTER html %]"> + [%~ constants.REMOTE_FILE FILTER html %]</a> cannot be downloaded + (reason: [% release.reason FILTER html %]).<br> + Either the remote server is temporarily unavailable, or your web server cannot access the web. If you are behind a proxy, set the <a href="editparams.cgi?section=advanced#proxy_url_desc">proxy_url</a> parameter correctly.</p> + [% ELSIF release.error == "no_write" %] + <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be created + (reason: [% release.reason FILTER html %]).<br> + Please make sure the web server can write into this directory. [% ELSIF release.error == "no_update" %] - <p>The local XML file '[% release.xml_file FILTER html %]' cannot be updated. + <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be updated. Please make sure the web server can edit this file.</p> [% ELSIF release.error == "no_access" %] - <p>The local XML file '[% release.xml_file FILTER html %]' cannot be read. + <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' cannot be read. Please make sure this file has the correct rights set on it.</p> [% ELSIF release.error == "corrupted" %] - <p>The local XML file '[% release.xml_file FILTER html %]' has an invalid XML format. + <p>The local XML file '[% constants.LOCAL_FILE FILTER html %]' has an invalid XML format. Please delete it and try accessing this page again.</p> [% ELSIF release.error == "unknown_parameter" %] <p>'[% Param("upgrade_notification") FILTER html %]' is not a valid notification diff --git a/template/en/default/search/search-specific.html.tmpl b/template/en/default/search/search-specific.html.tmpl index 277a90960..7e5de2c4a 100644 --- a/template/en/default/search/search-specific.html.tmpl +++ b/template/en/default/search/search-specific.html.tmpl @@ -119,7 +119,7 @@ for "crash secure SSL flash". <td></td> <td> - [% IF Param('specific_search_allow_empty_words') %] + [% IF Param('search_allow_no_criteria') %] <input type="submit" id="search" value="Search"> [% ELSE %] <input type="submit" id="search" value="Search" @@ -452,7 +452,15 @@ sub run_queries { 'params' => scalar $searchparams->Vars, 'user' => $args->{'recipient'}, # the search runs as the recipient ); - my $sqlquery = $search->sql; + # If a query fails for whatever reason, it shouldn't kill the script. + my $sqlquery = eval { $search->sql }; + if ($@) { + print STDERR get_text('whine_query_failed', { query_name => $thisquery->{'name'}, + author => $args->{'author'}, + reason => $@ }) . "\n"; + next; + } + $sth = $dbh->prepare($sqlquery); $sth->execute; |