From 645307b7dad849212762afcecf819a268cc810d3 Mon Sep 17 00:00:00 2001 From: "lpsolit%gmail.com" <> Date: Sun, 26 Feb 2006 07:10:23 +0000 Subject: Bug 284875: Move GetBugLink, GetAttachmentLink, and quoteUrls out of globals.pl - Patch by Frédéric Buclin r=mkanat a=justdave MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bugzilla/Bug.pm | 13 +--- Bugzilla/Template.pm | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 201 insertions(+), 12 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 71b6bc7f4..e2222ccb7 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -1221,7 +1221,7 @@ sub ValidateBugAlias { my $vars = {}; $vars->{'alias'} = $alias; if ($id) { - $vars->{'bug_link'} = &::GetBugLink($id, $id); + $vars->{'bug_id'} = $id; ThrowUserError("alias_in_use", $vars); } @@ -1294,19 +1294,12 @@ sub ValidateDependencies { my @deps = @{$deptree{'dependson'}}; my @blocks = @{$deptree{'blocked'}}; - my @union = (); - my @isect = (); my %union = (); my %isect = (); foreach my $b (@deps, @blocks) { $union{$b}++ && $isect{$b}++ } - @union = keys %union; - @isect = keys %isect; + my @isect = keys %isect; if (scalar(@isect) > 0) { - my $both = ""; - foreach my $i (@isect) { - $both .= &::GetBugLink($i, "#" . $i) . " "; - } - ThrowUserError("dependency_loop_multi", { both => $both }); + ThrowUserError("dependency_loop_multi", {'deps' => \@isect}); } return %deps; } diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 08bcfacdf..6327a31a5 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -218,6 +218,202 @@ sub get_format { }; } +# This routine quoteUrls contains inspirations from the HTML::FromText CPAN +# module by Gareth Rees . It has been heavily hacked, +# all that is really recognizable from the original is bits of the regular +# expressions. +# This has been rewritten to be faster, mainly by substituting 'as we go'. +# If you want to modify this routine, read the comments carefully + +sub quoteUrls { + my ($text, $curr_bugid) = (@_); + return $text unless $text; + + # We use /g for speed, but uris can have other things inside them + # (http://foo/bug#3 for example). Filtering that out filters valid + # bug refs out, so we have to do replacements. + # mailto can't contain space or #, so we don't have to bother for that + # Do this by escaping \0 to \1\0, and replacing matches with \0\0$count\0\0 + # \0 is used because its unliklely to occur in the text, so the cost of + # doing this should be very small + # Also, \0 won't appear in the value_quote'd bug title, so we don't have + # to worry about bogus substitutions from there + + # escape the 2nd escape char we're using + my $chr1 = chr(1); + $text =~ s/\0/$chr1\0/g; + + # However, note that adding the title (for buglinks) can affect things + # In particular, attachment matches go before bug titles, so that titles + # with 'attachment 1' don't double match. + # Dupe checks go afterwards, because that uses ^ and \Z, which won't occur + # if it was subsituted as a bug title (since that always involve leading + # and trailing text) + + # Because of entities, its easier (and quicker) to do this before escaping + + my @things; + my $count = 0; + my $tmp; + + # non-mailto protocols + my $protocol_re = qr/(afs|cid|ftp|gopher|http|https|irc|mid|news|nntp|prospero|telnet|view-source|wais)/i; + + $text =~ s~\b(${protocol_re}: # The protocol: + [^\s<>\"]+ # Any non-whitespace + [\w\/]) # so that we end in \w or / + ~($tmp = html_quote($1)) && + ($things[$count++] = "$tmp") && + ("\0\0" . ($count-1) . "\0\0") + ~egox; + + # We have to quote now, otherwise our html is itsself escaped + # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH + + $text = html_quote($text); + + # Color quoted text + $text =~ s~^(>.+)$~$1~mg; + $text =~ s~\n~\n~g; + + # mailto: + # Use | so that $1 is defined regardless + $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+)\b + ~$1$2~igx; + + # attachment links - handle both cases separately for simplicity + $text =~ s~((?:^Created\ an\ |\b)attachment\s*\(id=(\d+)\)(\s\[edit\])?) + ~($things[$count++] = get_attachment_link($2, $1)) && + ("\0\0" . ($count-1) . "\0\0") + ~egmx; + + $text =~ s~\b(attachment\s*\#?\s*(\d+)) + ~($things[$count++] = get_attachment_link($2, $1)) && + ("\0\0" . ($count-1) . "\0\0") + ~egmxi; + + # Current bug ID this comment belongs to + my $current_bugurl = $curr_bugid ? "show_bug.cgi?id=$curr_bugid" : ""; + + # This handles bug a, comment b type stuff. Because we're using /g + # we have to do this in one pattern, and so this is semi-messy. + # Also, we can't use $bug_re?$comment_re? because that will match the + # empty string + my $bug_re = qr/bug\s*\#?\s*(\d+)/i; + my $comment_re = qr/comment\s*\#?\s*(\d+)/i; + $text =~ s~\b($bug_re(?:\s*,?\s*$comment_re)?|$comment_re) + ~ # We have several choices. $1 here is the link, and $2-4 are set + # depending on which part matched + (defined($2) ? get_bug_link($2,$1,$3) : + "$1") + ~egox; + + # Old duplicate markers + $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) + (\d+) + (?=\ \*\*\*\Z) + ~get_bug_link($1, $1) + ~egmx; + + # Now remove the encoding hacks + $text =~ s/\0\0(\d+)\0\0/$things[$1]/eg; + $text =~ s/$chr1\0/\0/g; + + return $text; +} + +# Creates a link to an attachment, including its title. +sub get_attachment_link { + my ($attachid, $link_text) = @_; + my $dbh = Bugzilla->dbh; + + detaint_natural($attachid) + || die "get_attachment_link() called with non-integer attachment number"; + + my ($bugid, $isobsolete, $desc) = + $dbh->selectrow_array('SELECT bug_id, isobsolete, description + FROM attachments WHERE attach_id = ?', + undef, $attachid); + + if ($bugid) { + my $title = ""; + my $className = ""; + if (Bugzilla->user->can_see_bug($bugid)) { + $title = $desc; + } + if ($isobsolete) { + $className = "bz_obsolete"; + } + # Prevent code injection in the title. + $title = value_quote($title); + + $link_text =~ s/ \[edit\]$//; + my $linkval = "attachment.cgi?id=$attachid&action="; + # Whitespace matters here because these links are in
 tags.
+        return qq||
+               . qq|$link_text|
+               . qq| [edit]|
+               . qq||;
+    }
+    else {
+        return qq{$link_text};
+    }
+}
+
+# Creates a link to a bug, including its title.
+# It takes either two or three parameters:
+#  - The bug number
+#  - The link text, to place between the ..
+#  - An optional comment number, for linking to a particular
+#    comment in the bug
+
+sub get_bug_link {
+    my ($bug_num, $link_text, $comment_num) = @_;
+    my $dbh = Bugzilla->dbh;
+
+    if (!defined($bug_num) || ($bug_num eq "")) {
+        return "<missing bug number>";
+    }
+    my $quote_bug_num = html_quote($bug_num);
+    detaint_natural($bug_num) || return "<invalid bug number: $quote_bug_num>";
+
+    my ($bug_state, $bug_res, $bug_desc) =
+        $dbh->selectrow_array('SELECT bugs.bug_status, resolution, short_desc
+                               FROM bugs WHERE bugs.bug_id = ?',
+                               undef, $bug_num);
+
+    if ($bug_state) {
+        # 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) = ("", "", "");
+
+        $title = $bug_state;
+        if ($bug_state eq 'UNCONFIRMED') {
+            $pre = "";
+            $post = "";
+        }
+        elsif (! &::IsOpenedState($bug_state)) {
+            $pre = '';
+            $title .= " $bug_res";
+            $post = '';
+        }
+        if (Bugzilla->user->can_see_bug($bug_num)) {
+            $title .= " - $bug_desc";
+        }
+        # Prevent code injection in the title.
+        $title = value_quote($title);
+
+        my $linkval = "show_bug.cgi?id=$bug_num";
+        if (defined $comment_num) {
+            $linkval .= "#c$comment_num";
+        }
+        return qq{$pre$link_text$post};
+    }
+    else {
+        return qq{$link_text};
+    }
+}
+
 ###############################################################################
 # Templatization Code
 
@@ -406,7 +602,7 @@ sub create {
                                my ($context, $bug) = @_;
                                return sub {
                                    my $text = shift;
-                                   return &::quoteUrls($text, $bug);
+                                   return quoteUrls($text, $bug);
                                };
                            },
                            1
@@ -416,7 +612,7 @@ sub create {
                               my ($context, $bug) = @_;
                               return sub {
                                   my $text = shift;
-                                  return &::GetBugLink($bug, $text);
+                                  return get_bug_link($bug, $text);
                               };
                           },
                           1
-- 
cgit v1.2.3-24-g4f1b