IPv6 padding cleanup - removed trailing ':'
[lhc/web/wiklou.git] / includes / LinkFilter.php
index 0008c6a..dc4c125 100644 (file)
@@ -4,8 +4,8 @@
  * Some functions to help implement an external link filter for spam control.
  * 
  * TODO: implement the filter. Currently these are just some functions to help
- * maintenance/cleanupSpam.php remove links to a single specified domain. The 
- * next thing is to implement functions for checking a given page against a big 
+ * maintenance/cleanupSpam.php remove links to a single specified domain. The
+ * next thing is to implement functions for checking a given page against a big
  * list of domains.
  *
  * Another cool thing to do would be a web interface for fast spam removal.
@@ -14,7 +14,7 @@ class LinkFilter {
        /**
         * @static
         */
-       function matchEntry( $text, $filterEntry ) {
+       static function matchEntry( $text, $filterEntry ) {
                $regex = LinkFilter::makeRegex( $filterEntry );
                return preg_match( $regex, $text );
        }
@@ -22,10 +22,10 @@ class LinkFilter {
        /**
         * @static
         */
-       function makeRegex( $filterEntry ) {
+       private static function makeRegex( $filterEntry ) {
                $regex = '!http://';
                if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
-                       $regex .= '([A-Za-z0-9.-]+\.|)';
+                       $regex .= '(?:[A-Za-z0-9.-]+\.|)';
                        $filterEntry = substr( $filterEntry, 2 );
                }
                $regex .= preg_quote( $filterEntry, '!' ) . '!Si';
@@ -33,22 +33,25 @@ class LinkFilter {
        }
 
        /**
-        * Make a string to go after an SQL LIKE, which will match the specified 
+        * Make a string to go after an SQL LIKE, which will match the specified
         * string. There are several kinds of filter entry:
-        *     *.domain.com    -  Produces http://com.domain.%, matches domain.com 
+        *     *.domain.com    -  Produces http://com.domain.%, matches domain.com
         *                        and www.domain.com
         *     domain.com      -  Produces http://com.domain./%, matches domain.com
         *                        or domain.com/ but not www.domain.com
-        *     *.domain.com/x  -  Produces http://com.domain.%/x%, matches 
+        *     *.domain.com/x  -  Produces http://com.domain.%/x%, matches
         *                        www.domain.com/xy
-        *     domain.com/x    -  Produces http://com.domain./x%, matches 
+        *     domain.com/x    -  Produces http://com.domain./x%, matches
         *                        domain.com/xy but not www.domain.com/xy
         *
         * Asterisks in any other location are considered invalid.
         * 
         * @static
+        * @param $filterEntry String: domainparts
+        * @param $prot        String: protocol
         */
-       function makeLike( $filterEntry ) {
+        public static function makeLike( $filterEntry , $prot = 'http://' ) {
+               $db = wfGetDB( DB_MASTER );
                if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
                        $subdomains = true;
                        $filterEntry = substr( $filterEntry, 2 );
@@ -61,7 +64,7 @@ class LinkFilter {
                        $subdomains = false;
                }
                // No stray asterisks, that could cause confusion
-               // It's not simple or efficient to handle it properly so we don't 
+               // It's not simple or efficient to handle it properly so we don't
                // handle it at all.
                if ( strpos( $filterEntry, '*' ) !== false ) {
                        return false;
@@ -74,19 +77,32 @@ class LinkFilter {
                        $path = '/';
                        $host = $filterEntry;
                }
-               $host = strtolower( implode( '.', array_reverse( explode( '.', $host ) ) ) );
-               if ( substr( $host, -1, 1 ) !== '.' ) {
-                       $host .= '.';
-               }
-               $like = "http://$host";
-               
-               if ( $subdomains ) {
-                       $like .= '%';
-               }
-               if ( !$subdomains || $path !== '/' ) {
-                       $like .= $path . '%';
+               // Reverse the labels in the hostname, convert to lower case
+               // For emails reverse domainpart only
+               if ( $prot == 'mailto:' && strpos($host, '@') ) {
+                       // complete email adress 
+                       $mailparts = explode( '@', $host );
+                       $domainpart = strtolower( implode( '.', array_reverse( explode( '.', $mailparts[1] ) ) ) );
+                       $host = $domainpart . '@' . $mailparts[0];
+                       $like = $db->escapeLike( "$prot$host" ) . "%";
+               } elseif ( $prot == 'mailto:' ) {
+                       // domainpart of email adress only. do not add '.'
+                       $host = strtolower( implode( '.', array_reverse( explode( '.', $host ) ) ) );   
+                       $like = $db->escapeLike( "$prot$host" ) . "%";                  
+               } else {
+                       $host = strtolower( implode( '.', array_reverse( explode( '.', $host ) ) ) );   
+                       if ( substr( $host, -1, 1 ) !== '.' ) {
+                               $host .= '.';
+                       }
+                       $like = $db->escapeLike( "$prot$host" );
+
+                       if ( $subdomains ) {
+                               $like .= '%';
+                       }
+                       if ( !$subdomains || $path !== '/' ) {
+                               $like .= $db->escapeLike( $path ) . '%';
+                       }
                }
                return $like;
        }
 }
-?>