aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--globals.pl280
1 files changed, 63 insertions, 217 deletions
diff --git a/globals.pl b/globals.pl
index 0da5ec895..91bed7794 100644
--- a/globals.pl
+++ b/globals.pl
@@ -20,7 +20,6 @@
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
# Jake <jake@acutex.net>
-# Bradley Baetz <bbaetz@cs.mcgill.ca>
# Contains some global variables and routines used throughout bugzilla.
@@ -51,7 +50,6 @@ sub globals_pl_sillyness {
$zz = @main::milestoneurl;
$zz = @main::prodmaxvotes;
$zz = $main::superusergroupset;
- $zz = $main::userid;
}
#
@@ -73,11 +71,11 @@ use Date::Parse; # For str2time().
#use Carp; # for confess
use RelationSet;
-# Some environment variables are not taint safe
-delete $ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};
+# $ENV{PATH} is not taint safe
+delete $ENV{PATH};
# Contains the version string for the current running Bugzilla.
-$::param{'version'} = '2.15';
+$::param{'version'} = '2.14.1';
$::dontchange = "--do_not_change--";
$::chooseone = "--Choose_one:--";
@@ -104,8 +102,8 @@ sub ConnectToDatabase {
$name = Param("shadowdb");
$::dbwritesallowed = 0;
}
- $::db = DBI->connect("DBI:mysql:host=$::db_host;database=$name", $::db_user, $::db_pass)
- || die "Bugzilla is currently broken. Please try again later. " .
+ $::db = DBI->connect("DBI:mysql:host=$::db_host;database=$name", $::db_user, $::db_pass)
+ || die "Bugzilla is currently broken. Please try again later. " .
"If the problem persists, please contact " . Param("maintainer") .
". The error you should quote is: " . $DBI::errstr;
}
@@ -213,13 +211,8 @@ sub SendSQL {
}
SqlLog($str);
$::currentquery = $::db->prepare($str);
- if (!$::currentquery->execute) {
- my $errstr = $::db->errstr;
- # Cut down the error string to a reasonable.size
- $errstr = substr($errstr, 0, 2000) . ' ... ' . substr($errstr, -2000)
- if length($errstr) > 4000;
- die "$str: " . $errstr;
- }
+ $::currentquery->execute
+ || die "$str: " . $::db->errstr;
SqlLog("Done");
if (!$dontshadow && $iswrite && Param("shadowdb")) {
my $q = SqlQuote($str);
@@ -242,10 +235,10 @@ sub MoreSQLData {
return 0;
}
if (defined @::fetchahead) {
- return 1;
+ return 1;
}
if (@::fetchahead = $::currentquery->fetchrow_array) {
- return 1;
+ return 1;
}
return 0;
}
@@ -256,9 +249,9 @@ sub FetchSQLData {
return;
}
if (defined @::fetchahead) {
- my @result = @::fetchahead;
- undef @::fetchahead;
- return @result;
+ my @result = @::fetchahead;
+ undef @::fetchahead;
+ return @result;
}
return $::currentquery->fetchrow_array;
}
@@ -416,7 +409,7 @@ sub GenerateCode {
$result = "";
foreach my $k (sort { uc($a) cmp uc($b)} eval("keys $name")) {
$result .= GenerateCode("\$" . substr($name, 1) .
- "{" . PerlQuote($k) . "}");
+ "{'" . $k . "'}");
}
return $result;
} else {
@@ -530,13 +523,6 @@ sub GenerateVersionTable {
my $tmpname = "data/versioncache.$$";
open(FID, ">$tmpname") || die "Can't create $tmpname";
- print FID "#\n";
- print FID "# DO NOT EDIT!\n";
- print FID "# This file is automatically generated at least once every\n";
- print FID "# hour by the GenerateVersionTable() sub in globals.pl.\n";
- print FID "# Any changes you make will be overwritten.\n";
- print FID "#\n";
-
print FID GenerateCode('@::log_columns');
print FID GenerateCode('%::versions');
@@ -706,98 +692,6 @@ sub GenerateRandomPassword {
return $password;
}
-sub SelectVisible {
- my ($query, $userid, $usergroupset) = @_;
-
- # Run the SQL $query with the additional restriction that
- # the bugs can be seen by $userid. $usergroupset is provided
- # as an optimisation when this is already known, eg from CGI.pl
- # If not present, it will be obtained from the db.
- # Assumes that 'bugs' is mentioned as a table name. You should
- # also make sure that bug_id is qualified bugs.bug_id!
- # Your query must have a WHERE clause. This is unlikely to be a problem.
-
- # Also, note that mySQL requires aliases for tables to be locked, as well
- # This means that if you change the name from selectVisible_cc (or add
- # additional tables), you will need to update anywhere which does a
- # LOCK TABLE, and then calls routines which call this
-
- $usergroupset = 0 unless $userid;
-
- unless (defined($usergroupset)) {
- PushGlobalSQLState();
- SendSQL("SELECT groupset FROM profiles WHERE userid = $userid");
- $usergroupset = FetchOneColumn();
- PopGlobalSQLState();
- }
-
- # Users are authorized to access bugs if they are a member of all
- # groups to which the bug is restricted. User group membership and
- # bug restrictions are stored as bits within bitsets, so authorization
- # can be determined by comparing the intersection of the user's
- # bitset with the bug's bitset. If the result matches the bug's bitset
- # the user is a member of all groups to which the bug is restricted
- # and is authorized to access the bug.
-
- # A user is also authorized to access a bug if she is the reporter,
- # assignee, QA contact, or member of the cc: list of the bug and the bug
- # allows users in those roles to see the bug. The boolean fields
- # reporter_accessible, assignee_accessible, qacontact_accessible, and
- # cclist_accessible identify whether or not those roles can see the bug.
-
- # Bit arithmetic is performed by MySQL instead of Perl because bitset
- # fields in the database are 64 bits wide (BIGINT), and Perl installations
- # may or may not support integers larger than 32 bits. Using bitsets
- # and doing bitset arithmetic is probably not cross-database compatible,
- # however, so these mechanisms are likely to change in the future.
-
- my $replace = " ";
-
- if ($userid) {
- $replace .= "LEFT JOIN cc selectVisible_cc ON
- bugs.bug_id = selectVisible_cc.bug_id AND
- selectVisible_cc.who = $userid "
- }
-
- $replace .= "WHERE ((bugs.groupset & $usergroupset) = bugs.groupset ";
-
- if ($userid) {
- # There is a mysql bug affecting v3.22 and 3.23 (at least), where this will
- # cause all rows to be returned! We work arround this by adding an not isnull
- # test to the JOINed cc table. See http://lists.mysql.com/cgi-ez/ezmlm-cgi?9:mss:11417
- # Its needed, even though it shouldn't be
- $replace .= "OR (bugs.reporter_accessible = 1 AND bugs.reporter = $userid)
- OR (bugs.assignee_accessible = 1 AND bugs.assigned_to = $userid)
- OR (bugs.qacontact_accessible = 1 AND bugs.qa_contact = $userid)
- OR (bugs.cclist_accessible = 1 AND selectVisible_cc.who = $userid AND not isnull(selectVisible_cc.who))";
- }
-
- $replace .= ") AND ";
-
- $query =~ s/\sWHERE\s/$replace/i;
-
- return $query;
-}
-
-sub CanSeeBug {
- # Note that we pass in the usergroupset, since this is known
- # in most cases (ie viewing bugs). Maybe make this an optional
- # parameter?
-
- my ($id, $userid, $usergroupset) = @_;
-
- # Query the database for the bug, retrieving a boolean value that
- # represents whether or not the user is authorized to access the bug.
-
- PushGlobalSQLState();
- SendSQL(SelectVisible("SELECT bugs.bug_id FROM bugs WHERE bugs.bug_id = $id",
- $userid, $usergroupset));
-
- my $ret = defined(FetchSQLData());
- PopGlobalSQLState();
-
- return $ret;
-}
sub ValidatePassword {
# Determines whether or not a password is valid (i.e. meets Bugzilla's
@@ -929,22 +823,16 @@ sub DBNameToIdAndCheck {
exit(0);
}
-# Use trick_taint() when you know that there is no way that the data
+# Use detaint_string() when you know that there is no way that the data
# in a scalar can be tainted, but taint mode still bails on it.
# WARNING!! Using this routine on data that really could be tainted
# defeats the purpose of taint mode. It should only be
# used on variables that cannot be touched by users.
-sub trick_taint {
- $_[0] =~ /^(.*)$/s;
- $_[0] = $1;
- return (defined($_[0]));
-}
-
-sub detaint_natural {
- $_[0] =~ /^(\d+)$/;
- $_[0] = $1;
- return (defined($_[0]));
+sub detaint_string {
+ my ($str) = @_;
+ $str =~ m/^(.*)$/s;
+ $str = $1;
}
# This routine quoteUrls contains inspirations from the HTML::FromText CPAN
@@ -991,22 +879,6 @@ sub quoteUrls {
$things[$count++] = $item;
}
- # Either a comment string or no comma and a compulsory #.
- while ($text =~ s/\bbug(\s|%\#)*(\d+),?\s*comment\s*(\s|%\#)(\d+)/"##$count##"/ei) {
- my $item = $&;
- my $bugnum = $2;
- my $comnum = $4;
- $item = GetBugLink($bugnum, $item);
- $item =~ s/(id=\d+)/$1#c$comnum/;
- $things[$count++] = $item;
- }
- while ($text =~ s/\bcomment(\s|%\#)*(\d+)/"##$count##"/ei) {
- my $item = $&;
- my $num = $2;
- $item = value_quote($item);
- $item = qq{<A HREF="#c$num">$item</A>};
- $things[$count++] = $item;
- }
while ($text =~ s/\bbug(\s|%\#)*(\d+)/"##$count##"/ei) {
my $item = $&;
my $num = $2;
@@ -1039,7 +911,7 @@ sub quoteUrls {
}
$text = value_quote($text);
- $text =~ s/\&#013;/\n/g;
+ $text =~ s/\&#010;/\n/g;
# Stuff everything back from the array.
for (my $i=0 ; $i<$count ; $i++) {
@@ -1059,61 +931,40 @@ sub quoteUrls {
sub GetBugLink {
my ($bug_num, $link_text) = (@_);
- detaint_natural($bug_num) || die "GetBugLink() called with non-integer bug number";
-
- # If we've run GetBugLink() for this bug number before, %::buglink
- # will contain an anonymous array ref of relevent values, if not
- # we need to get the information from the database.
- if (! defined $::buglink{$bug_num}) {
- # Make sure any unfetched data from a currently running query
- # is saved off rather than overwritten
- PushGlobalSQLState();
+ my ($link_return) = "";
- SendSQL("SELECT bugs.bug_status, resolution, short_desc, groupset " .
- "FROM bugs WHERE bugs.bug_id = $bug_num");
-
- # If the bug exists, save its data off for use later in the sub
- if (MoreSQLData()) {
- my ($bug_state, $bug_res, $bug_desc, $bug_grp) = FetchSQLData();
- # Initialize these variables to be "" so that we don't get warnings
- # if we don't change them below (which is highly likely).
- my ($pre, $title, $post) = ("", "", "");
+ # TODO - Add caching capabilites... possibly use a global variable in the form
+ # of $buglink{$bug_num} that contains the text returned by this sub. If that
+ # variable is defined, simply return it's value rather than running the SQL
+ # query. This would cut down on the number of SQL calls when the same bug is
+ # referenced multiple times.
+
+ # Make sure any unfetched data from a currently running query
+ # is saved off rather than overwritten
+ PushGlobalSQLState();
+
+ # Get this bug's info from the SQL Database
+ SendSQL("select bugs.bug_status, resolution, short_desc, groupset
+ from bugs where bugs.bug_id = $bug_num");
+ my ($bug_stat, $bug_res, $bug_desc, $bug_grp) = (FetchSQLData());
+
+ # Format the retrieved information into a link
+ if ($bug_stat eq "UNCONFIRMED") { $link_return .= "<i>" }
+ if ($bug_res ne "") { $link_return .= "<strike>" }
+ $bug_desc = value_quote($bug_desc);
+ $link_text = value_quote($link_text);
+ $link_return .= qq{<a href="show_bug.cgi?id=$bug_num" title="$bug_stat};
+ if ($bug_res ne "") {$link_return .= " $bug_res"}
+ if ($bug_grp == 0) { $link_return .= " - $bug_desc" }
+ $link_return .= qq{">$link_text</a>};
+ if ($bug_res ne "") { $link_return .= "</strike>" }
+ if ($bug_stat eq "UNCONFIRMED") { $link_return .= "</i>"}
+
+ # Put back any query in progress
+ PopGlobalSQLState();
- $title = $bug_state;
- if ($bug_state eq $::unconfirmedstate) {
- $pre = "<i>";
- $post = "</i>";
- }
- elsif (! IsOpenedState($bug_state)) {
- $pre = "<strike>";
- $title .= " $bug_res";
- $post = "</strike>";
- }
- if ($bug_grp == 0 || CanSeeBug($bug_num, $::userid, $::usergroupset)) {
- $title .= " - $bug_desc";
- }
- $::buglink{$bug_num} = [$pre, value_quote($title), $post];
- }
- else {
- # Even if there's nothing in the database, we want to save a blank
- # anonymous array in the %::buglink hash so the query doesn't get
- # run again next time we're called for this bug number.
- $::buglink{$bug_num} = [];
- }
- # All done with this sidetrip
- PopGlobalSQLState();
- }
+ return $link_return;
- # Now that we know we've got all the information we're gonna get, let's
- # return the link (which is the whole reason we were called :)
- my ($pre, $title, $post) = @{$::buglink{$bug_num}};
- # $title will be undefined if the bug didn't exist in the database.
- if (defined $title) {
- return qq{$pre<a href="show_bug.cgi?id=$bug_num" title="$title">$link_text</a>$post};
- }
- else {
- return qq{$link_text};
- }
}
sub GetLongDescriptionAsText {
@@ -1184,14 +1035,16 @@ sub GetLongDescriptionAsHTML {
my ($who, $email, $when, $text) = (FetchSQLData());
$email .= Param('emailsuffix');
if ($count) {
- $result .= qq|<BR><BR><I>------- Additional Comment <a name="c$count" href="#c$count">#$count</a> From |;
- if ($who) {
- $result .= qq{<A HREF="mailto:$email">$who</A> };
- } else {
- $result .= qq{<A HREF="mailto:$email">$email</A> };
- }
-
- $result .= time2str("%Y-%m-%d %H:%M", str2time($when)) . " -------</I><BR>\n";
+ $result .= "<BR><BR><I>------- Additional Comments From ";
+ if ($who) {
+ $result .= qq{<A HREF="mailto:$email">$who</A> } .
+ time2str("%Y-%m-%d %H:%M", str2time($when)) .
+ " -------</I><BR>\n";
+ } else {
+ $result .= qq{<A HREF="mailto:$email">$email</A> } .
+ time2str("%Y-%m-%d %H:%M", str2time($when)) .
+ " -------</I><BR>\n";
+ }
}
$result .= "<PRE>" . quoteUrls(\%knownattachments, $text) . "</PRE>\n";
$count++;
@@ -1233,7 +1086,7 @@ sub SplitEnumType {
while ($guts =~ /^\'([^\']*)\',(.*)$/) {
push @result, $1;
$guts = $2;
- }
+ }
}
return @result;
}
@@ -1249,7 +1102,7 @@ sub SqlQuote {
$str =~ s/([\\\'])/\\$1/g;
$str =~ s/\0/\\0/g;
# If it's been SqlQuote()ed, then it's safe, so we tell -T that.
- trick_taint($str);
+ $str = detaint_string($str);
return "'$str'";
}
@@ -1318,19 +1171,12 @@ sub GroupIsActive {
sub IsOpenedState {
my ($state) = (@_);
- if (grep($_ eq $state, OpenStates())) {
+ if ($state =~ /^(NEW|REOPENED|ASSIGNED)$/ || $state eq $::unconfirmedstate) {
return 1;
}
return 0;
}
-# This sub will return an array containing any status that
-# is considered an open bug.
-
-sub OpenStates {
- return ('NEW', 'REOPENED', 'ASSIGNED', $::unconfirmedstate);
-}
-
sub RemoveVotes {
my ($id, $who, $reason) = (@_);