2008-07-31 16:28:24 +00:00
|
|
|
<?php
|
|
|
|
if ( ! defined( 'MEDIAWIKI' ) )
|
|
|
|
die();
|
2008-08-02 11:10:42 +00:00
|
|
|
|
|
|
|
class AbuseFilterException extends MWException {}
|
2008-07-31 16:28:24 +00:00
|
|
|
|
|
|
|
class AbuseFilterParserNative {
|
|
|
|
var $mVars;
|
|
|
|
var $mProcess,$mPipes;
|
|
|
|
|
|
|
|
public function __destruct() {
|
2008-08-02 11:10:42 +00:00
|
|
|
if (is_array($this->mPipes)) {
|
|
|
|
foreach( $this->mPipes as $pipe ) {
|
|
|
|
fclose($pipe);
|
|
|
|
}
|
2008-07-31 16:28:24 +00:00
|
|
|
}
|
|
|
|
|
2008-08-02 11:10:42 +00:00
|
|
|
if (is_resource($this->mProcess)) {
|
|
|
|
proc_terminate( $this->mProcess );
|
|
|
|
}
|
2008-07-31 16:28:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setVar( $name, $var ) {
|
|
|
|
$this->mVars[$name] = $var;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setVars( $vars ) {
|
|
|
|
foreach( $vars as $name => $var ) {
|
|
|
|
$this->setVar( $name, $var );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getNativeParser() {
|
|
|
|
global $wgAbuseFilterNativeParser;
|
|
|
|
|
|
|
|
if (!is_resource($this->mProcess)) {
|
|
|
|
$this->mPipes = array();
|
|
|
|
$descriptorspec = array(
|
|
|
|
0 => array( 'pipe', 'r' ),
|
|
|
|
1 => array( 'pipe', 'w' )
|
|
|
|
);
|
|
|
|
|
2008-08-02 13:51:29 +00:00
|
|
|
$this->mProcess = proc_open( $wgAbuseFilterNativeParser, $descriptorspec, $this->mPipes );
|
2008-07-31 16:28:24 +00:00
|
|
|
|
|
|
|
if (!is_resource($this->mProcess)) {
|
|
|
|
throw new MWException( "Error using native parser" );
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->mPipes;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->mPipes;
|
|
|
|
}
|
|
|
|
|
2008-08-02 11:10:42 +00:00
|
|
|
public function checkSyntax( $filter ) {
|
|
|
|
global $wgAbuseFilterNativeSyntaxCheck;
|
|
|
|
|
|
|
|
// Check the syntax of $filter
|
|
|
|
$pipes = array();
|
|
|
|
$descriptorspec = array(
|
|
|
|
0 => array( 'pipe', 'r' ),
|
|
|
|
1 => array( 'pipe', 'w' )
|
|
|
|
);
|
|
|
|
|
2008-08-02 13:51:29 +00:00
|
|
|
$proc = proc_open( $wgAbuseFilterNativeSyntaxCheck, $descriptorspec, $pipes );
|
2008-08-02 11:10:42 +00:00
|
|
|
|
|
|
|
if (!is_resource( $proc )) {
|
|
|
|
throw new MWException( "Unable to check syntax of filter." );
|
|
|
|
}
|
|
|
|
|
|
|
|
fwrite( $pipes[0], $filter );
|
|
|
|
fflush( $pipes[0] );
|
|
|
|
fclose( $pipes[0] );
|
|
|
|
|
|
|
|
$response = trim(fgets( $pipes[1] ) );
|
|
|
|
|
2008-08-03 14:04:26 +00:00
|
|
|
if ($response == "SUCCESS") {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
list ($discard,$error) = explode( ":", $response, 2 );
|
|
|
|
return $error;
|
|
|
|
}
|
2008-08-02 11:10:42 +00:00
|
|
|
}
|
|
|
|
|
2008-07-31 16:28:24 +00:00
|
|
|
public function parse( $filter ) {
|
|
|
|
$request = $this->generateXMLRequest( $filter );
|
|
|
|
|
|
|
|
$pipes = $this->getNativeParser();
|
|
|
|
|
|
|
|
if (is_array($pipes)) {
|
|
|
|
fwrite($pipes[0], $request);
|
|
|
|
fwrite($pipes[0], "\x04");
|
|
|
|
fflush($pipes[0]);
|
|
|
|
|
|
|
|
// Get response
|
|
|
|
$response = trim(fgets( $pipes[1] ));
|
|
|
|
|
|
|
|
if ($response == "MATCH") {
|
|
|
|
return true;
|
|
|
|
} elseif ($response == "NOMATCH") {
|
|
|
|
return false;
|
2008-08-02 11:10:42 +00:00
|
|
|
} elseif (in_string( 'EXCEPTION', $response ) ) {
|
|
|
|
throw new AbuseFilterException( "Native parser $response" );
|
2008-07-31 16:28:24 +00:00
|
|
|
} else {
|
2008-08-02 11:10:42 +00:00
|
|
|
throw new AbuseFilterException( "Unknown output from native parser: $response" );
|
2008-07-31 16:28:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function generateXMLRequest( $filter ) {
|
|
|
|
// Write vars
|
|
|
|
$vars = '';
|
|
|
|
foreach( $this->mVars as $key => $value ) {
|
|
|
|
$vars .= Xml::element( 'var', array( 'key' => $key ), utf8_encode($value) );
|
|
|
|
}
|
|
|
|
$vars = Xml::tags( 'vars', null, $vars );
|
|
|
|
|
|
|
|
$code = Xml::element( 'rule', null, utf8_encode($filter) );
|
|
|
|
|
|
|
|
$request = Xml::tags( 'request', null, $vars . $code );
|
|
|
|
|
|
|
|
return $request;
|
|
|
|
}
|
|
|
|
}
|