mediawiki-extensions-AbuseF.../parser_native/afutils.cpp
Andrew Garrett b283904b81 AbuseFilter native parser:
* Revert r38187 for now:
** Introduced a memory leak.
** Used an unnecessary library. The point is taken, and this will be fixed in a few days (using glibc instead).
* Fix logic error in boolean ops.
* Integrate with the PHP abuse filter using AbuseFilterParserNative class.
* Fix memory leak.
* Fix a few miscellaneous bugs
2008-07-31 16:28:24 +00:00

140 lines
3.1 KiB
C++
Executable file

#include "afutils.h"
#include <math.h>
#include <boost/regex.hpp>
AFPData af_boolInvert( AFPData value ) {
bool bVal = !value.toBool();
AFPData d(bVal);
return d;
}
AFPData af_pow( AFPData base, AFPData exponent ) {
float b = base.toFloat();
float e = exponent.toFloat();
float result = pow(b,e);
return AFPData(result);
}
AFPData af_keywordIn( AFPData needle, AFPData haystack ) {
string n = needle.toString();
string h = haystack.toString();
bool result = h.find(n,0) != h.npos;
return AFPData(result);
}
AFPData af_unaryMinus( AFPData data ) {
float v = data.toFloat();
return AFPData(-v);
}
AFPData af_boolOp( AFPData a, AFPData b, string op ) {
bool v1 = a.toBool();
bool v2 = b.toBool();
if (op == "|") {
return AFPData( v1 || v2 );
} else if (op == "&") {
return AFPData( v1 && v2 );
} else if (op == "^") {
return AFPData( (v1 || v2) && !(v1 && v2) );
}
throw AFPException( "Invalid boolean operation." );
}
AFPData af_compareOp( AFPData a, AFPData b, string op ) {
string s1 = a.toString();
string s2 = b.toString();
float f1 = a.toFloat();
float f2 = b.toFloat();
unsigned int t1 = a.getType();
unsigned int t2 = b.getType();
if (op == "==") {
return AFPData( s1 == s2 );
} else if (op == "!=") {
return AFPData( s1 != s2 );
} else if (op == "===") {
return AFPData( s1 == s2 && t1 == t2 );
} else if (op == "!==") {
return AFPData( s1 != s2 || t1 != t2 );
} else if (op == ">") {
return AFPData( f1 > f2 );
} else if (op == "<") {
return AFPData( f1 < f2 );
} else if (op == ">=") {
return AFPData( f1 >= f2 );
} else if (op == "<=") {
return AFPData( f1 <= f2 );
}
throw AFPException( "Invalid comparison type" );
}
AFPData af_mulRel( AFPData a, AFPData b, string op ) {
float f1 = a.toFloat();
float f2 = b.toFloat();
if (op == "*") {
return AFPData( f1 * f2 );
} else if (op == "/") {
return AFPData( f1 / f2 );
} else if (op == "%") {
int i1 = a.toInt();
int i2 = b.toInt();
return AFPData( (double)(i1 % i2) );
}
throw AFPException( "Invalid multiplication-related operator" );
}
AFPData af_sum( AFPData a, AFPData b ) {
if (a.getType() == D_STRING || b.getType() == D_STRING) {
return AFPData( a.toString() + b.toString() );
} else {
return AFPData( a.toFloat() * b.toFloat() );
}
}
AFPData af_sub( AFPData a, AFPData b ) {
return AFPData( a.toFloat() - b.toFloat() );
}
bool isInVector( string needle, vector<string> haystack ) {
for( vector<string>::iterator it=haystack.begin(); it!=haystack.end(); ++it ) {
string test = *it;
if (test == needle.c_str()) { return true; }
}
return false;
}
AFPData af_keyword( string keyword, AFPData a, AFPData b ) {
if (keyword == "in") {
string needle = a.toString();
string haystack = b.toString();
bool result = (haystack.find( needle, 0 ) != haystack.npos);
return AFPData( result );
} else if (keyword == "like") {
boost::regex rx( b.toString() );
string test = a.toString();
bool result = regex_match( test, rx );
return AFPData( result );
}
throw AFPException( "Unknown keyword %s", keyword );
}