Add contains_any function, for searching a single haystack for multiple needles. Implemented with FSS with a fallback to a for loop, so it should be really fast.

This commit is contained in:
Andrew Garrett 2009-03-26 02:03:32 +00:00
parent d4d2f4913d
commit c597c1915f
3 changed files with 35 additions and 0 deletions

View file

@ -65,6 +65,7 @@ class AbuseFilter {
'rmwhitespace(text)' => 'rmwhitespace',
'rmspecials(text)' => 'rmspecials',
'ip_in_range(ip, range)' => 'ip_in_range',
'contains_any(haystack,needle1,needle2,needle3)' => 'contains-any',
),
'vars' => array(
'accountname' => 'accountname',

View file

@ -246,6 +246,7 @@ Please ask a user with permission to add restricted actions to make the change f
'abusefilter-edit-builder-funcs-rmwhitespace' => 'Remove whitespace',
'abusefilter-edit-builder-funcs-rmspecials' => 'Remove special characters',
'abusefilter-edit-builder-funcs-ip_in_range' => 'Is IP in range?',
'abusefilter-edit-builder-funcs-contains-any' => 'Search string for multiple substrings',
'abusefilter-edit-builder-group-vars' => 'Variables',
'abusefilter-edit-builder-vars-accountname' => 'Account name (on account creation)',
'abusefilter-edit-builder-vars-action' => 'Action',

View file

@ -302,6 +302,7 @@ class AbuseFilterParser {
'count' => 'funcCount',
'rcount' => 'funcRCount',
'ip_in_range' => 'funcIPInRange',
'contains_any' => 'funcContainsAny',
);
// Order is important. The punctuation-matching regex requires that
@ -1140,6 +1141,38 @@ class AbuseFilterParser {
return new AFPData( AFPData::DString, $s );
}
protected function funcContainsAny( $args ) {
if (count( $args ) < 2 ) {
throw new AFPException( "Not enough params to ".__METHOD__ );
}
$s = array_shift( $args );
$s = $s->toString();
$searchStrings = array();
foreach( $args as $arg ) {
$searchStrings[] = $arg->toString();
}
if ( function_exists( 'fss_prep_search' ) ) {
$fss = fss_prep_search( $searchStrings );
$result = fss_exec_search( $fss, $s );
$ok = is_array($result);
} else {
$ok = false;
foreach( $searchStrings as $needle ) {
if (in_string( $needle, $s ) ) {
$ok = true;
break;
}
}
}
return new AFPData( AFPData::DBool, $ok );
}
protected function ccnorm( $s ) {
if (!class_exists( 'AntiSpoof' ) ) {
return $s;