diff options
Diffstat (limited to 'extensions/ConfirmEdit/Captcha.php')
-rw-r--r-- | extensions/ConfirmEdit/Captcha.php | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/extensions/ConfirmEdit/Captcha.php b/extensions/ConfirmEdit/Captcha.php index 9967dd47..b15de61f 100644 --- a/extensions/ConfirmEdit/Captcha.php +++ b/extensions/ConfirmEdit/Captcha.php @@ -42,6 +42,7 @@ class SimpleCaptcha { Xml::element( 'input', array( 'name' => 'wpCaptchaWord', 'id' => 'wpCaptchaWord', + 'size' => 5, 'autocomplete' => 'off', 'tabindex' => 1 ) ) . // tab in before the edit textarea "</p>\n" . @@ -354,26 +355,38 @@ class SimpleCaptcha { */ function filterLink( $url ) { global $wgCaptchaWhitelist; - $source = wfMessage( 'captcha-addurl-whitelist' )->inContentLanguage()->text(); + static $regexes = null; - $whitelist = wfMessage( 'captcha-addurl-whitelist', $source )->isDisabled() - ? false - : $this->buildRegexes( explode( "\n", $source ) ); + if ( $regexes === null ) { + $source = wfMessage( 'captcha-addurl-whitelist' )->inContentLanguage(); - $cwl = $wgCaptchaWhitelist !== false ? preg_match( $wgCaptchaWhitelist, $url ) : false; - $wl = $whitelist !== false ? preg_match( $whitelist, $url ) : false; + $regexes = $source->isDisabled() + ? array() + : $this->buildRegexes( explode( "\n", $source->plain() ) ); - return !( $cwl || $wl ); + if ( $wgCaptchaWhitelist !== false ) { + array_unshift( $regexes, $wgCaptchaWhitelist ); + } + } + + foreach ( $regexes as $regex ) { + if ( preg_match( $regex, $url ) ) { + return false; + } + } + + return true; } /** * Build regex from whitelist * @param $lines string from [[MediaWiki:Captcha-addurl-whitelist]] - * @return string Regex or bool false if whitelist is empty + * @return array Regexes * @access private */ function buildRegexes( $lines ) { # Code duplicated from the SpamBlacklist extension (r19197) + # and later modified. # Strip comments and whitespace, then remove blanks $lines = array_filter( array_map( 'trim', preg_replace( '/#.*$/', '', $lines ) ) ); @@ -381,34 +394,59 @@ class SimpleCaptcha { # No lines, don't make a regex which will match everything if ( count( $lines ) == 0 ) { wfDebug( "No lines\n" ); - return false; + return array(); } else { # Make regex # It's faster using the S modifier even though it will usually only be run once // $regex = 'http://+[a-z0-9_\-.]*(' . implode( '|', $lines ) . ')'; // return '/' . str_replace( '/', '\/', preg_replace('|\\\*/|', '/', $regex) ) . '/Si'; - $regexes = ''; - $regexStart = '/^https?:\/\/+[a-z0-9_\-.]*('; - $regexEnd = ')/Si'; + $regexes = array(); + $regexStart = array( + 'normal' => '/^https?:\/\/+[a-z0-9_\-.]*(?:', + 'noprotocol' => '/^(?:', + ); + $regexEnd = array( + 'normal' => ')/Si', + 'noprotocol' => ')/Si', + ); $regexMax = 4096; - $build = false; + $build = array(); foreach ( $lines as $line ) { + # Extract flags from the line + $options = array(); + if ( preg_match( '/^(.*?)\s*<([^<>]*)>$/', $line, $matches ) ) { + if ( $matches[1] === '' ) { + wfDebug( "Line with empty regex\n" ); + continue; + } + $line = $matches[1]; + $opts = preg_split( '/\s*\|\s*/', trim( $matches[2] ) ); + foreach ( $opts as $opt ) { + $opt = strtolower( $opt ); + if ( $opt == 'noprotocol' ) { + $options['noprotocol'] = true; + } + } + } + + $key = isset( $options['noprotocol'] ) ? 'noprotocol' : 'normal'; + // FIXME: not very robust size check, but should work. :) - if ( $build === false ) { - $build = $line; - } elseif ( strlen( $build ) + strlen( $line ) > $regexMax ) { - $regexes .= $regexStart . - str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) . - $regexEnd; - $build = $line; + if ( !isset( $build[$key] ) ) { + $build[$key] = $line; + } elseif ( strlen( $build[$key] ) + strlen( $line ) > $regexMax ) { + $regexes[] = $regexStart[$key] . + str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build[$key] ) ) . + $regexEnd[$key]; + $build[$key] = $line; } else { - $build .= '|' . $line; + $build[$key] .= '|' . $line; } } - if ( $build !== false ) { - $regexes .= $regexStart . - str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) . - $regexEnd; + foreach ( $build as $key => $value ) { + $regexes[] = $regexStart[$key] . + str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build[$key] ) ) . + $regexEnd[$key]; } return $regexes; } |