]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 277782: _throw_error should unlock tables when tables are locked, automatically
authormkanat%kerio.com <>
Sat, 5 Mar 2005 08:18:47 +0000 (08:18 +0000)
committermkanat%kerio.com <>
Sat, 5 Mar 2005 08:18:47 +0000 (08:18 +0000)
Patch By Tomas Kopal <Tomas.Kopal@altap.cz> r=travis, r=LpSolit, a=justdave

12 files changed:
Bugzilla/Auth/Login/WWW/CGI.pm
Bugzilla/Bug.pm
Bugzilla/Error.pm
CGI.pl
editclassifications.cgi
editcomponents.cgi
editmilestones.cgi
editusers.cgi
editversions.cgi
globals.pl
post_bug.cgi
process_bug.cgi

index 42e454f86b03b4ea963cd9345b7456239388012f..47c2b92b729dff6f8e84022ef54963bc0e6dc743 100644 (file)
@@ -184,7 +184,7 @@ sub login {
 
     # If we get here, then we've run out of options, which shouldn't happen
     ThrowCodeError("authres_unhandled", { authres => $authres, 
-                                          type => $type, });
+                                          type => $type });
 }
 
 # This auth style allows the user to log out.
index a6758d36fa36566194c62e72efa18758b587fade..b2261e1ee18b9dd4f68782705b9ac573d087e0f9 100755 (executable)
@@ -511,21 +511,18 @@ sub ValidateTime {
     # (allow negatives, though, so people can back out errors in time reporting)
     if ($time !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/) {
         ThrowUserError("number_not_numeric",
-                       {field => "$field", num => "$time"},
-                       "abort");
+                       {field => "$field", num => "$time"});
     }
 
     # Only the "work_time" field is allowed to contain a negative value.
     if ( ($time < 0) && ($field ne "work_time") ) {
         ThrowUserError("number_too_small",
-                       {field => "$field", num => "$time", min_num => "0"},
-                       "abort");
+                       {field => "$field", num => "$time", min_num => "0"});
     }
 
     if ($time > 99999.99) {
         ThrowUserError("number_too_large",
-                       {field => "$field", num => "$time", max_num => "99999.99"},
-                       "abort");
+                       {field => "$field", num => "$time", max_num => "99999.99"});
     }
 }
 
index 4c6288a2851e86a23b0f55fbab54d7b911ca9030..6eac5c94b62f6da90d403aa8bc8e22c0b8dcf68d 100644 (file)
@@ -32,13 +32,15 @@ use Bugzilla::Util;
 use Date::Format;
 
 sub _throw_error {
-    my ($name, $error, $vars, $unlock_tables) = @_;
+    my ($name, $error, $vars) = @_;
 
     $vars ||= {};
 
     $vars->{error} = $error;
 
-    Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT) if $unlock_tables;
+    # Make sure any locked tables are unlocked
+    # and the transaction is rolled back (if supported)
+    Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT);
 
     # If a writable data/errorlog exists, log error details there.
     if (-w "data/errorlog") {
@@ -95,6 +97,10 @@ sub ThrowCodeError {
 sub ThrowTemplateError {
     my ($template_err) = @_;
 
+    # Make sure any locked tables are unlocked
+    # and the transaction is rolled back (if supported)
+    Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT);
+
     my $vars = {};
     if (Bugzilla->batch) {
         die("error: template error: $template_err");
@@ -149,16 +155,16 @@ Bugzilla::Error - Error handling utilities for Bugzilla
   ThrowUserError("error_tag",
                  { foo => 'bar' });
  
-  # supplying "abort" to ensure tables are unlocked
-  ThrowUserError("another_error_tag",
-                 { foo => 'bar' }, 'abort');
-
 =head1 DESCRIPTION
 
 Various places throughout the Bugzilla codebase need to report errors to the
 user. The C<Throw*Error> family of functions allow this to be done in a
 generic and localisable manner.
 
+These functions automatically unlock the database tables, if there were any
+locked. They will also roll back the transaction, if it is supported by
+the underlying DB.
+
 =head1 FUNCTIONS
 
 =over 4
@@ -170,12 +176,6 @@ of variables as a second argument. These are used by the
 I<global/user-error.html.tmpl> template to format the error, using the passed
 in variables as required.
 
-An optional third argument may be supplied. If present, the error
-handling code will unlock the database tables: it is a Bugzilla standard
-to provide the string "abort" as the argument value. In the long term,
-this argument will go away, to be replaced by transactional C<rollback>
-calls. There is no timeframe for doing so, however.
-
 =item C<ThrowCodeError>
 
 This function is used when an internal check detects an error of some sort.
diff --git a/CGI.pl b/CGI.pl
index 69ec8f64f8be7ac9107b98f23a2e7f7f153c4906..d650ea08ed807c14aeb1b259274a058da7052deb 100644 (file)
--- a/CGI.pl
+++ b/CGI.pl
@@ -112,7 +112,7 @@ sub CheckFormField (\%$;\@) {
             $field = $fieldname;
         }
         
-        ThrowCodeError("illegal_field", { field => $field }, "abort");
+        ThrowCodeError("illegal_field", { field => $field });
       }
 }
 
@@ -213,7 +213,7 @@ sub CheckEmailSyntax {
     my ($addr) = (@_);
     my $match = Param('emailregexp');
     if ($addr !~ /$match/ || $addr =~ /[\\\(\)<>&,;:"\[\] \t\r\n]/) {
-        ThrowUserError("illegal_email_address", { addr => $addr }, 'abort');
+        ThrowUserError("illegal_email_address", { addr => $addr });
     }
 }
 
index a390ed4c6f3d6ed7601936fc107147df448a42b2..deeffdce76438a1a6b204957f7c22becaee09115 100755 (executable)
@@ -300,12 +300,10 @@ if ($action eq 'update') {
 
     if ($classification ne $classificationold) {
         unless ($classification) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError("classification_not_specified")
         }
         
         if (TestClassification($classification)) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError("classification_already_exists", { name => $classification });
         }
         $sth = $dbh->prepare("UPDATE classifications
index 12a25905d612805466d706d347b4197b10bdd00d..d21518fceaa7a2558a4a14b45422a5a689f2afea 100755 (executable)
@@ -66,7 +66,7 @@ sub CheckProduct ($)
 
     # do we have a product?
     unless ($prod) {
-        ThrowUserError('product_not_specified');    
+        ThrowUserError('product_not_specified');
         exit;
     }
 
@@ -585,7 +585,6 @@ if ($action eq 'update') {
 
     if ($description ne $descriptionold) {
         unless ($description) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('component_blank_description',
                            {'name' => $componentold});
             exit;
@@ -603,7 +602,6 @@ if ($action eq 'update') {
 
         my $initialownerid = login_to_id($initialowner);
         unless ($initialownerid) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('component_need_valid_initialowner',
                            {'name' => $componentold});
             exit;
@@ -621,7 +619,6 @@ if ($action eq 'update') {
     if (Param('useqacontact') && $initialqacontact ne $initialqacontactold) {
         my $initialqacontactid = login_to_id($initialqacontact);
         if (!$initialqacontactid && $initialqacontact ne '') {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('component_need_valid_initialqacontact',
                            {'name' => $componentold});
             exit;
@@ -638,13 +635,11 @@ if ($action eq 'update') {
 
     if ($component ne $componentold) {
         unless ($component) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('component_must_have_a_name',
                            {'name' => $componentold});
             exit;
         }
         if (TestComponent($product, $component)) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('component_already_exists',
                            {'name' => $component});
             exit;
index 7364d4d0668cfe9d4105e39697b9a1445676267d..7317e72204480682e0461f2e80cf23e410681fd9 100755 (executable)
@@ -59,14 +59,14 @@ sub CheckProduct ($)
 
     # do we have a product?
     unless ($product) {
-        &::ThrowUserError('product_not_specified');    
+        ThrowUserError('product_not_specified');    
         exit;
     }
 
     # Does it exist in the DB?
     unless (TestProduct $product) {
-        &::ThrowUserError('product_doesnt_exist',
-                          {'product' => $product});
+        ThrowUserError('product_doesnt_exist',
+                       {'product' => $product});
         exit;
     }
 }
@@ -506,12 +506,9 @@ if ($action eq 'update') {
     my $stored_sortkey = $sortkey;
     if ($sortkey != $sortkeyold) {
         if (!detaint_natural($sortkey)) {
-
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('milestone_sortkey_invalid',
                            {'name' => $milestone,
                             'sortkey' => $stored_sortkey});
-
             exit;
         }
 
@@ -532,12 +529,10 @@ if ($action eq 'update') {
 
     if ($milestone ne $milestoneold) {
         unless ($milestone) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('milestone_blank_name');
             exit;
         }
         if (TestMilestone($product, $milestone)) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('milestone_already_exists',
                            {'name' => $milestone,
                             'product' => $product});
index 87a8b69bde97e04605ffeb5d67d5905de8b5c530..8169d0b937df328dc00154e3efe91b8d10862922 100755 (executable)
@@ -212,8 +212,7 @@ if ($action eq 'search') {
     canSeeUser($otherUserID)
         || ThrowUserError('auth_failure', {reason => "not_visible",
                                            action => "modify",
-                                           object => "user"},
-                          'abort');
+                                           object => "user"});
 
     # Cleanups
     my $login           = trim($cgi->param('login')           || '');
@@ -231,11 +230,10 @@ if ($action eq 'search') {
 
         if ($login ne $loginold) {
             # Validate, then trick_taint.
-            $login || ThrowUserError('user_login_required', undef, 'abort');
+            $login || ThrowUserError('user_login_required');
             CheckEmailSyntax($login);
             is_available_username($login) || ThrowUserError('account_exists',
-                                                            {'email' => $login},
-                                                             'abort');
+                                                            {'email' => $login});
             trick_taint($login);
             push(@changedFields, 'login_name');
             push(@values, $login);
@@ -493,19 +491,17 @@ if ($action eq 'search') {
                          'whine_events WRITE');
 
     Param('allowuserdeletion')
-        || ThrowUserError('users_deletion_disabled', undef, 'abort');
+        || ThrowUserError('users_deletion_disabled');
     $editusers || ThrowUserError('auth_failure',
                                  {group  => "editusers",
                                   action => "delete",
-                                  object => "users"},
-                                 'abort');
+                                  object => "users"});
     canSeeUser($otherUserID) || ThrowUserError('auth_failure',
                                                {reason => "not_visible",
                                                 action => "delete",
-                                                object => "user"},
-                                               'abort');
+                                                object => "user"});
     productResponsibilities($otherUserID)
-        && ThrowUserError('user_has_responsibility', undef, 'abort');
+        && ThrowUserError('user_has_responsibility');
 
     Bugzilla->logout_user_by_id($otherUserID);
 
index ee4a83d774b63f29d9c9e2ef2962ce7320631ef5..60f60057eb19f6828c5cd2ed9dfc36274f9c6230 100755 (executable)
@@ -406,16 +406,13 @@ if ($action eq 'update') {
 
     if ($version ne $versionold) {
         unless ($version) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('version_blank_name');
             exit;
         }
         if (TestVersion($product,$version)) {
-            $dbh->bz_unlock_tables(UNLOCK_ABORT);
             ThrowUserError('version_already_exists',
                            {'name' => $version,
                             'product' => $product});
-
             exit;
         }
         SendSQL("UPDATE bugs
index e71493f6b90612bf2bd99140f1ca5189aa22af9e..44bf7dc3ea33fa53ee3b529f31e95103c83450f0 100644 (file)
@@ -613,11 +613,11 @@ sub ValidatePassword {
     my ($password, $matchpassword) = @_;
     
     if (length($password) < 3) {
-        ThrowUserError("password_too_short", undef, 'abort');
+        ThrowUserError("password_too_short");
     } elsif (length($password) > 16) {
-        ThrowUserError("password_too_long", undef, 'abort');
+        ThrowUserError("password_too_long");
     } elsif ((defined $matchpassword) && ($password ne $matchpassword)) {
-        ThrowUserError("passwords_dont_match", undef, 'abort');
+        ThrowUserError("passwords_dont_match");
     }
 }
 
@@ -649,8 +649,7 @@ sub DBNameToIdAndCheck {
         return $result;
     }
 
-    ThrowUserError("invalid_username",
-                   { name => $name }, "abort");
+    ThrowUserError("invalid_username", { name => $name });
 }
 
 sub get_classification_id {
index 6b52b447da2625ec80519e31a3d844da6e2e4e92..d701a91721dee5fac7160faa4997f1981cf8718b 100755 (executable)
@@ -318,8 +318,7 @@ if (UserInGroup("editbugs") && defined($::FORM{'dependson'})) {
                 }
 
                 ThrowUserError("dependency_loop_multi",
-                               { both => $both },
-                               "abort");
+                               { both => $both });
             }
         }
         my $tmp = $me;
@@ -378,14 +377,14 @@ foreach my $b (grep(/^bit-\d*$/, keys %::FORM)) {
     if ($::FORM{$b}) {
         my $v = substr($b, 4);
         $v =~ /^(\d+)$/
-          || ThrowCodeError("group_id_invalid", undef, "abort");
+          || ThrowCodeError("group_id_invalid");
         if (!GroupIsActive($v)) {
             # Prevent the user from adding the bug to an inactive group.
             # Should only happen if there is a bug in Bugzilla or the user
             # hacked the "enter bug" form since otherwise the UI 
             # for adding the bug to the group won't appear on that form.
             $vars->{'bit'} = $v;
-            ThrowCodeError("inactive_group", undef, "abort");
+            ThrowCodeError("inactive_group");
         }
         SendSQL("SELECT user_id FROM user_group_map 
                  WHERE user_id = $::userid
index ea2180c3c2006fc62e694c5246f74205d653f386..1fb54d2a418e77534766bd932269a2fdc4b766f4 100755 (executable)
@@ -109,7 +109,7 @@ foreach my $field ("estimated_time", "work_time", "remaining_time") {
 if (UserInGroup(Param('timetrackinggroup'))) {
     my $wk_time = $::FORM{'work_time'};
     if ($::FORM{'comment'} =~ /^\s*$/ && $wk_time && $wk_time != 0) {
-        ThrowUserError('comment_required', undef, "abort");
+        ThrowUserError('comment_required');
     }
 }
 
@@ -241,7 +241,7 @@ if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct)
         $vars->{'newvalue'} = $::FORM{'product'};
         $vars->{'field'} = 'product';
         $vars->{'privs'} = $PrivilegesRequired;
-        ThrowUserError("illegal_change", $vars, "abort");
+        ThrowUserError("illegal_change", $vars);
     }
 
     CheckFormField(\%::FORM, 'product', \@::legal_product);
@@ -1232,7 +1232,7 @@ foreach my $id (@idlist) {
                 $vars->{'field'} = $col;
             }
             $vars->{'privs'} = $PrivilegesRequired;
-            ThrowUserError("illegal_change", $vars, "abort");
+            ThrowUserError("illegal_change", $vars);
         }
     }
 
@@ -1251,13 +1251,13 @@ foreach my $id (@idlist) {
         $vars->{'newvalue'} = "no keywords";
         $vars->{'field'} = "keywords";
         $vars->{'privs'} = $PrivilegesRequired;
-        ThrowUserError("illegal_change", $vars, "abort");
+        ThrowUserError("illegal_change", $vars);
     }
 
     $oldhash{'product'} = get_product_name($oldhash{'product_id'});
     if (!CanEditProductId($oldhash{'product_id'})) {
         ThrowUserError("product_edit_denied",
-                      { product => $oldhash{'product'} }, "abort");
+                      { product => $oldhash{'product'} });
     }
 
     if (defined $::FORM{'product'} 
@@ -1265,7 +1265,7 @@ foreach my $id (@idlist) {
         && $::FORM{'product'} ne $oldhash{'product'}
         && !CanEnterProduct($::FORM{'product'})) {
         ThrowUserError("entry_access_denied",
-                       { product => $::FORM{'product'} }, "abort");
+                       { product => $::FORM{'product'} });
     }
     if ($requiremilestone) {
         # musthavemilestoneonaccept applies only if at least two
@@ -1283,7 +1283,7 @@ foreach my $id (@idlist) {
             # if musthavemilestoneonaccept == 1, then the target
             # milestone must be different from the default one.
             if ($value eq $defaultmilestone) {
-                ThrowUserError("milestone_required", { bug_id => $id }, "abort");
+                ThrowUserError("milestone_required", { bug_id => $id });
             }
         }
     }   
@@ -1319,7 +1319,7 @@ foreach my $id (@idlist) {
                 next if $i eq "";
                 
                 if ($id eq $i) {
-                    ThrowUserError("dependency_loop_single", undef, "abort");
+                    ThrowUserError("dependency_loop_single");
                 }
                 if (!exists $seen{$i}) {
                     push(@{$deptree{$target}}, $i);
@@ -1363,8 +1363,7 @@ foreach my $id (@idlist) {
                     }
 
                     ThrowUserError("dependency_loop_multi",
-                                   { both => $both },
-                                   "abort");
+                                   { both => $both });
                 }
             }
             my $tmp = $me;
@@ -1573,6 +1572,7 @@ foreach my $id (@idlist) {
                     shift @oldlist;
                 } else {
                     if ($oldlist[0] != $newlist[0]) {
+                        $dbh->bz_unlock_tables(UNLOCK_ABORT);
                         die "Error in list comparing code";
                     }
                     shift @oldlist;