Daimona Eaytoy has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/391065 )
Change subject: Add contains_all function ...................................................................... Add contains_all function Added the contains_all function, with basically the same role as contains_any but using logic AND instead of OR. Co-authored with Valerio Bozzolan. Bug: T21176 Change-Id: Ib0a8b783db6ce0d5db64771c8e0c70f0f8d13d36 --- M i18n/en.json M i18n/qqq.json M includes/AbuseFilter.class.php M includes/parser/AbuseFilterParser.php 4 files changed, 47 insertions(+), 16 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/AbuseFilter refs/changes/65/391065/1 diff --git a/i18n/en.json b/i18n/en.json index 1a6ccf5..98c1773 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -235,7 +235,8 @@ "abusefilter-edit-builder-funcs-rmwhitespace": "Remove whitespace (rmwhitespace)", "abusefilter-edit-builder-funcs-rmspecials": "Remove special characters (rmspecials)", "abusefilter-edit-builder-funcs-ip_in_range": "Is IP in range? (ip_in_range)", - "abusefilter-edit-builder-funcs-contains-any": "Search string for multiple substrings (contains_any)", + "abusefilter-edit-builder-funcs-contains-any": "Search string for multiple substrings in OR mode. (contains_any)", + "abusefilter-edit-builder-funcs-contains-all": "Search string for multiple substrings in AND mode. (contains_all)", "abusefilter-edit-builder-funcs-substr": "Substring (substr)", "abusefilter-edit-builder-funcs-strpos": "Position of substring in string (strpos)", "abusefilter-edit-builder-funcs-str_replace": "Replace substring with string (str_replace)", diff --git a/i18n/qqq.json b/i18n/qqq.json index 522cc1b..9302446 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -267,6 +267,7 @@ "abusefilter-edit-builder-funcs-rmspecials": "{{doc-important|Do not translate \"'''rmspecials'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-ip_in_range": "{{doc-important|Do not translate \"'''ip_in_range'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-contains-any": "{{doc-important|Do not translate \"'''contains_any'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", + "abusefilter-edit-builder-funcs-contains-all": "{{doc-important|Do not translate \"'''contains_all'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-substr": "{{doc-important|Do not translate \"'''substr'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-strpos": "{{doc-important|Do not translate \"'''strpos'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", "abusefilter-edit-builder-funcs-str_replace": "{{doc-important|Do not translate \"'''str_replace'''\".}} Abuse filter syntax option in a dropdown from the group {{msg-mw|abusefilter-edit-builder-group-funcs}}.", diff --git a/includes/AbuseFilter.class.php b/includes/AbuseFilter.class.php index f58a46a..270666a 100644 --- a/includes/AbuseFilter.class.php +++ b/includes/AbuseFilter.class.php @@ -81,6 +81,7 @@ 'rmspecials(text)' => 'rmspecials', 'ip_in_range(ip, range)' => 'ip_in_range', 'contains_any(haystack,needle1,needle2,...)' => 'contains-any', + 'contains_all(haystack,needle1,needle2,...)' => 'contains-all', 'substr(subject, offset, length)' => 'substr', 'strpos(haystack, needle)' => 'strpos', 'str_replace(subject, search, replace)' => 'str_replace', diff --git a/includes/parser/AbuseFilterParser.php b/includes/parser/AbuseFilterParser.php index 89f5a62..fbbf424 100644 --- a/includes/parser/AbuseFilterParser.php +++ b/includes/parser/AbuseFilterParser.php @@ -31,6 +31,7 @@ 'get_matches' => 'funcGetMatches', 'ip_in_range' => 'funcIPInRange', 'contains_any' => 'funcContainsAny', + 'contains_all' => 'funcContainsAll', 'substr' => 'funcSubstr', 'strlen' => 'funcLen', 'strpos' => 'funcStrPos', @@ -1137,9 +1138,28 @@ $s = array_shift( $args ); - return new AFPData( AFPData::DBOOL, self::containsAny( $s, $args ) ); + return new AFPData( AFPData::DBOOL, self::contains( 'ANY', $s, $args ) ); } + /** + * @param array $args + * @return AFPData + * @throws AFPUserVisibleException + */ + protected function funcContainsAll( $args ) { + if ( count( $args ) < 2 ) { + throw new AFPUserVisibleException( + 'notenoughargs', + $this->mCur->pos, + [ 'contains_all', 2, count( $args ) ] + ); + } + + $s = array_shift( $args ); + + return new AFPData( AFPData::DBOOL, self::contains( 'ALL', $s, $args, false ) ); + } + /** * Normalize and search a string for multiple substrings * @@ -1158,24 +1178,28 @@ $s = array_shift( $args ); - return new AFPData( AFPData::DBOOL, self::containsAny( $s, $args, true ) ); + return new AFPData( AFPData::DBOOL, self::contains( 'ANY', $s, $args, true ) ); } /** * Search for substrings in a string * + * Use logic to determine wether to use logic AND (ALL) or OR (ANY). + * * Use normalize = true to make use of ccnorm and * normalize both sides of the search. * + * @param string $logic Must be 'ANY' or 'ALL' * @param AFData $string * @param AFData[] $values * @param bool $normalize * * @return bool */ - protected static function containsAny( $string, $values, $normalize = false ) { - $string = $string->toString(); + protected static function contains( $logic = 'ANY', $string, $values, $normalize = false ) { + $is_any = 'ANY' === $logic; + $string = $string->toString(); if ( $string == '' ) { return false; } @@ -1184,23 +1208,27 @@ $string = self::ccnorm( $string ); } - $values = array_map( function ( $val ) use ( $normalize ) { - $str = $val->toString(); + foreach ( $values as $needle ) { + $needle = $needle->toString(); if ( $normalize ) { - $str = AbuseFilterParser::ccnorm( $str ); + $needle = AbuseFilterParser::ccnorm( $needle ); + } + if( $needle === '' ) { + // Bug #62203: Keep empty parameters from causing PHP warnings + continue; } - return $str; - }, $values ); - - foreach ( $values as $needle ) { - // Bug #60203: Keep empty parameters from causing PHP warnings - if ( $needle !== '' && strpos( $string, $needle ) !== false ) { - return true; + $is_found = strpos( $string, $needle ) !== false; + if( $is_found === $is_any ) { + // If I'm here and it's ANY it means that something is found. Just enough! Found! + // If I'm here and it's ALL it means that something isn't found. Just enough! Not found! + return $is_found; } } - return false; + // If I'm here and it's ANY it means that nothing was found: return false (because $is_any is true) + // If I'm here and it's ALL it means that everything were found: return true (because $is_any is false) + return ! $is_any; } /** -- To view, visit https://gerrit.wikimedia.org/r/391065 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib0a8b783db6ce0d5db64771c8e0c70f0f8d13d36 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/AbuseFilter Gerrit-Branch: master Gerrit-Owner: Daimona Eaytoy <daimona.w...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits