diff --git a/WordPressVIPMinimum/Sniffs/Functions/StripTagsSniff.php b/WordPressVIPMinimum/Sniffs/Functions/StripTagsSniff.php
index ce9fb845..5c1bb62b 100644
--- a/WordPressVIPMinimum/Sniffs/Functions/StripTagsSniff.php
+++ b/WordPressVIPMinimum/Sniffs/Functions/StripTagsSniff.php
@@ -9,6 +9,7 @@
namespace WordPressVIPMinimum\Sniffs\Functions;
+use PHPCSUtils\Utils\PassedParameters;
use WordPressCS\WordPress\AbstractFunctionParameterSniff;
/**
@@ -43,16 +44,60 @@ class StripTagsSniff extends AbstractFunctionParameterSniff {
* in lowercase.
* @param array $parameters Array with information about the parameters.
*
- * @return int|void Integer stack pointer to skip forward or void to continue
- * normal file processing.
+ * @return void
*/
public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) {
- if ( count( $parameters ) === 1 ) {
- $message = '`strip_tags()` does not strip CSS and JS in between the script and style tags. Use `wp_strip_all_tags()` to strip all tags.';
- $this->phpcsFile->addWarning( $message, $stackPtr, 'StripTagsOneParameter' );
- } elseif ( isset( $parameters[2] ) ) {
+ $string_param = PassedParameters::getParameterFromStack( $parameters, 1, 'string' );
+ $allowed_tags_param = PassedParameters::getParameterFromStack( $parameters, 2, 'allowed_tags' );
+
+ if ( $string_param !== false && $allowed_tags_param === false ) {
+ $this->add_warning( $stackPtr, 'StripTagsOneParameter' );
+ } elseif ( $allowed_tags_param !== false ) {
$message = '`strip_tags()` does not strip CSS and JS in between the script and style tags. Use `wp_kses()` instead to allow only the HTML you need.';
$this->phpcsFile->addWarning( $message, $stackPtr, 'StripTagsTwoParameters' );
+ } else {
+ $this->add_warning( $stackPtr );
}
}
+
+ /**
+ * Process the function if no parameters were found.
+ *
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $group_name The name of the group which was matched.
+ * @param string $matched_content The token content (function name) which was matched
+ * in lowercase.
+ *
+ * @return void
+ */
+ public function process_no_parameters( $stackPtr, $group_name, $matched_content ) {
+ $this->add_warning( $stackPtr );
+ }
+
+ /**
+ * Process the function if it is used as a first class callable.
+ *
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $group_name The name of the group which was matched.
+ * @param string $matched_content The token content (function name) which was matched
+ * in lowercase.
+ *
+ * @return void
+ */
+ public function process_first_class_callable( $stackPtr, $group_name, $matched_content ) {
+ $this->add_warning( $stackPtr );
+ }
+
+ /**
+ * Add a warning if the function is used at all.
+ *
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $error_code Error code to use for the warning.
+ *
+ * @return void
+ */
+ private function add_warning( $stackPtr, $error_code = 'Used' ) {
+ $message = '`strip_tags()` does not strip CSS and JS in between the script and style tags. Use `wp_strip_all_tags()` to strip all tags.';
+ $this->phpcsFile->addWarning( $message, $stackPtr, $error_code );
+ }
}
diff --git a/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.inc b/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.inc
index 1e625c4e..2636026c 100644
--- a/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.inc
+++ b/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.inc
@@ -1,13 +1,48 @@
haxx0red';
-$html = '
';
+/*
+ * Not the sniff target.
+ */
+use strip_tags;
+use MyNs\{
+ function strip_tags,
+};
+
+my\ns\strip_tags($a, $b);
+$this->strip_tags($a, $b);
+$this?->strip_tags($a, $b);
+MyClass::strip_tags($a, $b);
+echo STRIP_TAGS;
+namespace\strip_tags($a, $b);
+
+// Looks like a function call, but is a PHP 8.0+ class instantiation via an attribute.
+#[Strip_tags('text')]
+function foo() {}
strip_tag( 'Test', $html ); // Ok - similarly-named function.
wp_strip_all_tags( $string ); // Ok.
+
+/*
+ * These should all be flagged with a warning.
+ */
strip_tags( 'Testing' ); // Warning.
-strip_tags( 'Test', $html ); // Warning.
-strip_tags( 'Test' . ', ' . 'HTML' ); // Warning - concatenation on first parameter.
-strip_tags( 'Test, String', $html ); // Warning - comma in first parameter.
-strip_tags( $string ); // Warning.
+STRIP_TAGS( 'Test', $html ); // Warning.
+\strip_tags( 'Test' . ', ' . 'HTML', ); // Warning.
+strip_tags( 'Test, String', $html, ); // Warning.
+Strip_Tags( $string ); // Warning.
+
+// The function should always be flagged, even during live coding (missing required parameter).
+strip_tags();
+
+strip_tags(...$params); // PHP 5.6 argument unpacking.
+
+// Safeguard correct handling of function calls using PHP 8.0+ named parameters.
+strip_tags(allowed_tags: $allowed, string: $html ); // Warning.
+strip_tags(string: $html); // Warning.
+strip_tags(allowed_tags: $allowed); // Warning. Invalid function call, but that's not the concern of this sniff.
+
+\strip_tags(string: $html, allowed_tag: $allowed); // Warning (mind: deliberate typo in param name).
+strip_tags(html: $html); // Warning (mind: deliberately using incorrect param name).
+
+add_action('my_action', strip_tags(...)); // PHP 8.1 first class callable.
diff --git a/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.php b/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.php
index 3dfe3703..cd5ebf6c 100644
--- a/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.php
+++ b/WordPressVIPMinimum/Tests/Functions/StripTagsUnitTest.php
@@ -32,11 +32,19 @@ public function getErrorList() {
*/
public function getWarningList() {
return [
- 9 => 1,
- 10 => 1,
- 11 => 1,
- 12 => 1,
- 13 => 1,
+ 29 => 1,
+ 30 => 1,
+ 31 => 1,
+ 32 => 1,
+ 33 => 1,
+ 36 => 1,
+ 38 => 1,
+ 41 => 1,
+ 42 => 1,
+ 43 => 1,
+ 45 => 1,
+ 46 => 1,
+ 48 => 1,
];
}
}