]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 30345: Can mark bugs duplicates of each other [dupe loops] - Patch by Frédéric...
authorlpsolit%gmail.com <>
Wed, 31 Aug 2005 07:47:07 +0000 (07:47 +0000)
committerlpsolit%gmail.com <>
Wed, 31 Aug 2005 07:47:07 +0000 (07:47 +0000)
process_bug.cgi
template/en/default/global/user-error.html.tmpl

index 9ff3d83c6a16d06d35c0ccd999273366469f097e..7cebab2bbcc05d62cea01fe4df56eddc9e5f6c00 100755 (executable)
@@ -1023,20 +1023,18 @@ SWITCH: for ($cgi->param('knob')) {
         last SWITCH;
     };
     /^duplicate$/ && CheckonComment( "duplicate" ) && do {
+        # You cannot mark bugs as duplicates when changing
+        # several bugs at once.
+        unless (defined $cgi->param('id')) {
+            ThrowUserError('dupe_not_allowed');
+        }
+
         # Make sure we can change the original bug (issue A on bug 96085)
         CheckFormFieldDefined($cgi, 'dup_id');
         $duplicate = $cgi->param('dup_id');
         ValidateBugID($duplicate, 'dup_id');
         $cgi->param('dup_id', $duplicate);
 
-        # Also, let's see if the reporter has authorization to see
-        # the bug to which we are duping. If not we need to prompt.
-        DuplicateUserConfirm();
-
-        if (!defined $cgi->param('id') || $duplicate == $cgi->param('id')) {
-            ThrowUserError("dupe_of_self_disallowed");
-        }
-
         # Make sure the bug is not already marked as a dupe
         # (may appear in race condition)
         my $dupe_of =
@@ -1047,6 +1045,32 @@ SWITCH: for ($cgi->param('knob')) {
             ThrowUserError("dupe_entry_found", { dupe_of => $dupe_of });
         }
 
+        # Make sure a loop isn't created when marking this bug
+        # as duplicate.
+        my %dupes;
+        $dupe_of = $duplicate;
+        my $sth = $dbh->prepare('SELECT dupe_of FROM duplicates
+                                 WHERE dupe = ?');
+
+        while ($dupe_of) {
+            if ($dupe_of == $cgi->param('id')) {
+                ThrowUserError('dupe_loop_detected', { bug_id  => $cgi->param('id'),
+                                                       dupe_of => $duplicate });
+            }
+            # If $dupes{$dupe_of} is already set to 1, then a loop
+            # already exists which does not involve this bug.
+            # As the user is not responsible for this loop, do not
+            # prevent him from marking this bug as a duplicate.
+            last if exists $dupes{"$dupe_of"};
+            $dupes{"$dupe_of"} = 1;
+            $sth->execute($dupe_of);
+            $dupe_of = $sth->fetchrow_array;
+        }
+
+        # Also, let's see if the reporter has authorization to see
+        # the bug to which we are duping. If not we need to prompt.
+        DuplicateUserConfirm();
+
         # DUPLICATE bugs should have no time remaining.
         _remove_remaining_time();
 
index 992c6d89b5423e0957045c968c3266347d8187ba..8fb3139d299f1edfa8921eae40fb6256f9230961 100644 (file)
     This [% terms.bug %] has already been marked as a duplicate
     of [% terms.bug %] [%+ dupe_of FILTER html %].
 
-  [% ELSIF error == "dupe_of_self_disallowed" %]
-    [% title = "Cannot mark $terms.abug as a duplicate of itself" %]
-    You can't mark [% terms.abug %] as a duplicate of itself.
+  [% ELSIF error == "dupe_not_allowed" %]
+    [% title = "Cannot mark $terms.bugs as duplicates" %]
+    You cannot mark [% terms.bugs %] as duplicates when
+    changing several [% terms.bugs %] at once.
+
+  [% ELSIF error == "dupe_loop_detected" %]
+    [% title = "Loop detected among duplicates" %]
+    You cannot mark [% terms.bug %] [%+ bug_id FILTER html %] as
+    a duplicate of
+    [% IF dupe_of == bug_id %]
+      itself
+    [% ELSE %]
+      [%+ terms.bug %] [%+ dupe_of FILTER html %], because it
+      would create a duplicate loop
+    [% END %].
 
   [% ELSIF error == "email_change_in_progress" %]
     [% title = "Email Change Already In Progress" %]