Просмотр исходного кода

Hopefully fix the endless loops when matching URLs

Morten Brix Pedersen 24 лет назад
Родитель
Сommit
45f5f6e883
3 измененных файлов с 52 добавлено и 71 удалено
  1. 16 11
      modules/Pisg/Common.pm
  2. 8 25
      modules/Pisg/HTMLGenerator.pm
  3. 28 35
      modules/Pisg/Parser/Logfile.pm

+ 16 - 11
modules/Pisg/Common.pm

@@ -8,7 +8,7 @@ Pisg::Common - some common functions of pisg.
 
 use Exporter;
 @ISA = ('Exporter');
-@EXPORT = qw(add_alias add_aliaswild add_ignore add_url_ignore is_ignored url_is_ignored find_alias match_url match_email htmlentities);
+@EXPORT = qw(add_alias add_aliaswild add_ignore add_url_ignore is_ignored url_is_ignored find_alias match_urls match_email htmlentities);
 
 use strict;
 $^W = 1;
@@ -105,34 +105,39 @@ sub find_alias
     return $nick;
 }
 
-sub match_url
+sub match_urls
 {
-    my ($str) = @_;
+    my $str = shift;
+
+    # Interpret 'www.' as 'http://www.'
+    $str =~ s/(http:\/\/)?www\./http:\/\/www\./ig;
 
-    if ($str =~ /(http|https|ftp|telnet|news)(:\/\/[-a-zA-Z0-9_\/~]+\.[-a-zA-Z0-9.,_~=:&@%?#\/+]+)/) { 
+    my @urls;
+    while ($str =~ s/(http|https|ftp|telnet|news)(:\/\/[-a-zA-Z0-9_\/~]+\.[-a-zA-Z0-9.,_~=:&@%?#\/+]+)//i) { 
         my $url = "$1$2";
         if ($url_seen{$url}) {
-            return $url;
+            push(@urls, $url);
         } elsif ($url =~ s/\/$//) {
             if ($url_seen{$url}) {
-                return $url;
+                push(@urls, $url);
             } else {
                 $url_seen{"$url/"} = 1;
-                return "$url/";
+                push(@urls, "$url/");
             }
         } elsif ($url_seen{"$url/"}) {
-            return "$url/";
+            push(@urls, "$url/");
         } else {
             $url_seen{$url} = 1;
-            return $url;
+            push(@urls, $url);
         }
     }
-    return undef;
+
+    return @urls;
 }
 
 sub match_email
 {
-    my ($str) = @_;
+    my $str = shift;
 
     if ($str =~ /([-a-zA-Z0-9._]+@[-a-zA-Z0-9_]+\.[-a-zA-Z0-9._]+)/) {
         return $1;

+ 8 - 25
modules/Pisg/HTMLGenerator.pm

@@ -1536,35 +1536,18 @@ sub _replace_links
     # Sub to replace urls and e-mail addys to links
     my $str = shift;
     my $nick = shift;
-    my ($url, $email, $replaced, $return_str);
 
+    # Regular expressions are taken from match_urls() and match_email() in
+    # Common.pm
 
-    $str =~ s/(http:\/\/)?www\./http:\/\/www\./ig;
-    $return_str = $str;
-    $replaced = 0;
-     if ($nick) {
-        if ($url = match_url($str)) {
-            $return_str =~ s/(\Q$url\E)/<a href="$1" target="_blank" title="Open in new window: $1">$nick<\/a>/g;
-        }
-        if ($email = match_email($str)) {
-            $return_str =~ s/(\Q$email\E)/<a href="mailto:$1" title="Mail to $nick">$nick<\/a>/g;
-        }
+    if ($nick) {
+        $str =~ s/(http|https|ftp|telnet|news)(:\/\/[-a-zA-Z0-9_\/~]+\.[-a-zA-Z0-9.,_~=:&amp;@%?#\/+]+)/<a href="$1$2" target="_blank" title="Open in new window: $1$2">$nick<\/a>/g;
+        $str =~ s/([-a-zA-Z0-9._]+@[-a-zA-Z0-9_]+\.[-a-zA-Z0-9._]+)/<a href="mailto:$1" title="Mail to $nick">$nick<\/a>/g;
     } else {
-        while ($replaced < 1) {
-            $replaced = 1;
-            if ($url = match_url($str)) {
-                $return_str =~ s/(?<!(<a href="))(\Q$url\E)(?![-a-zA-Z0-9.,_~=:;&@%?#\/+]+)/<a href="$2" target="_blank" title="Open in new window: $2">$2<\/a>/g;
-                $str =~ s/(\Q$url\E)//g;
-                $replaced--;
-            }
-            if ($email = match_email($str)) {
-                $return_str =~ s/(\Q$email\E)/<a href="mailto:$1" title="Mail to $1">$1<\/a>/g;
-                $str =~ s/(\Q$email\E)//g;
-                $replaced--;
-            }
-        }
+        $str =~ s/(http|https|ftp|telnet|news)(:\/\/[-a-zA-Z0-9_\/~]+\.[-a-zA-Z0-9.,_~=:&amp;@%?#\/+]+)/<a href="$1$2" target="_blank" title="Open in new window: $1$2">$1$2<\/a>/g;
+        $str =~ s/([-a-zA-Z0-9._]+@[-a-zA-Z0-9_]+\.[-a-zA-Z0-9._]+)/<a href="mailto:$1" title="Mail to $1">$1<\/a>/g;
     }
-    return $return_str;
+    return $str;
 }
 
 sub _user_linetimes

+ 28 - 35
modules/Pisg/Parser/Logfile.pm

@@ -125,18 +125,18 @@ sub _parse_dir
     if (defined $self->{cfg}->{logsuffix}) {
         my @temparray;
         my %months = (
-            'jan'	=> '0',
-            'feb'	=> '1',
-            'mar'	=> '2',
-            'apr'	=> '3',
-            'may'	=> '4',
-            'jun'	=> '5',
-            'jul'	=> '6',
-            'aug'	=> '7',
-            'sep'	=> '8',
-            'oct'	=> '9',
-            'nov'	=> '10',
-            'dec'	=> '11',
+            'jan' => '0',
+            'feb' => '1',
+            'mar' => '2',
+            'apr' => '3',
+            'may' => '4',
+            'jun' => '5',
+            'jul' => '6',
+            'aug' => '7',
+            'sep' => '8',
+            'oct' => '9',
+            'nov' => '10',
+            'dec' => '11',
         );
         my ($mreg, $dreg, $yreg) = split(/\|\|/, $self->{cfg}->{logsuffix});
         my (@month, @day, @year);
@@ -226,7 +226,7 @@ sub _parse_file
                 if ($hour < $state->{oldtime}) { $stats->{days}++ }
                 $state->{oldtime} = $hour;
 
-                unless (is_ignored($nick)) {
+                if (!is_ignored($nick)) {
                     $stats->{totallines}++;
 
                     # Timestamp collecting
@@ -260,10 +260,10 @@ sub _parse_file
                     $stats->{lengths}{$nick} += $len;
 
                     $stats->{questions}{$nick}++
-                        if ($saying =~ /\?/);
+                        if (index($saying, "?") > -1);
 
                     $stats->{shouts}{$nick}++
-                        if ($saying =~ /!/);
+                        if (index($saying, "!") > -1);
 
                     if ($saying !~ /[a-z]/ && $saying =~ /[A-Z]/) {
                         # Ignore single smileys on a line. eg. '<user> :P'
@@ -287,19 +287,13 @@ sub _parse_file
                     }
 
                     # Find URLs
-                    my $check_str = $saying;                                                   
-                    $check_str =~ s/(http:\/\/)?www\./http:\/\/www\./ig;                       
-                    my $replaced = 0;                                                          
-                    while ($replaced < 1) {                                                    
-                        $replaced = 1;                                                         
-                        if (my $url = match_url($check_str)) {                                 
-                            unless(url_is_ignored($url)) {                                     
-                                $stats->{urlcounts}{$url}++;                                   
-                                $stats->{urlnicks}{$url} = $nick;                              
-                            }                                                                  
-                            $check_str =~ s/(\Q$url\E)//g;                                     
-                            $replaced--;                                                       
-                        }                                                                      
+                    if (my @urls = match_urls($saying)) {
+                        foreach (@urls) {
+                            if(!url_is_ignored($_)) {
+                                $stats->{urlcounts}{$_}++;
+                                $stats->{urlnicks}{$_} = $nick;
+                            }
+                        }
                     }
 
                     $self->_parse_words($stats, $saying, $nick);
@@ -322,7 +316,7 @@ sub _parse_file
             if ($hour < $state->{oldtime}) { $stats->{days}++ }
             $state->{oldtime} = $hour;
 
-            unless (is_ignored($nick)) {
+            if (!is_ignored($nick)) {
                 # Timestamp collecting
                 $stats->{times}{$hour}++;
 
@@ -334,7 +328,7 @@ sub _parse_file
 
                 if ($saying =~ /^($self->{cfg}->{violent}) (\S+)/) {
                     my $victim = find_alias($2);
-                    unless (is_ignored($victim)) {
+                    if (!is_ignored($victim)) {
                         $stats->{violence}{$nick}++;
                         $stats->{attacked}{$victim}++;
                         push @{ $lines->{violencelines}{$nick} }, $line;
@@ -351,8 +345,7 @@ sub _parse_file
         }
 
         # Match *** lines.
-        elsif (($hashref = $self->{parser}->thirdline($line, $linecount)) and
-        $hashref->{nick}) {
+        elsif (($hashref = $self->{parser}->thirdline($line, $linecount)) and $hashref->{nick}) {
             $stats->{totallines}++;
 
             my ($hour, $min, $nick, $kicker, $newtopic, $newmode, $newjoin);
@@ -371,21 +364,21 @@ sub _parse_file
             if ($hour < $state->{oldtime}) { $stats->{days}++ }
             $state->{oldtime} = $hour;
 
-            unless (is_ignored($nick)) {
+            if (!is_ignored($nick)) {
                 # Timestamp collecting
                 $stats->{times}{$hour}++;
 
                 $stats->{lastvisited}{$nick} = $stats->{days};
 
                 if (defined($kicker)) {
-                    unless (is_ignored($kicker)) {
+                    if (!is_ignored($kicker)) {
                         $stats->{kicked}{$kicker}++;
                         $stats->{gotkicked}{$nick}++;
                         push @{ $lines->{kicklines}{$nick} }, $line;
                     }
 
                 } elsif (defined($newtopic)) {
-                    unless ($newtopic eq '') {
+                    if ($newtopic ne '') {
                         my $tcount;
                         if (defined $stats->{topics}) {
                             $tcount = @{ $stats->{topics} };