From d93667e9ce4e45d455f3e8d2d3164e87748823ba Mon Sep 17 00:00:00 2001 From: Rebecca Hum Date: Thu, 4 Oct 2018 13:22:43 -0600 Subject: [PATCH] RestrictedHook: Add new sniff Use of the `upload_mimes` filter should generate a warning. This new sniff allows for other filters and action hooks to generate a custom warning when they are used. Fixes #87. See #231. --- WordPress-VIP-Go/ruleset.xml | 4 + .../Sniffs/Filters/RestrictedHookSniff.php | 102 ++++++++++++++++++ .../Tests/Filters/RestrictedHookUnitTest.inc | 19 ++++ .../Tests/Filters/RestrictedHookUnitTest.php | 50 +++++++++ 4 files changed, 175 insertions(+) create mode 100644 WordPressVIPMinimum/Sniffs/Filters/RestrictedHookSniff.php create mode 100644 WordPressVIPMinimum/Tests/Filters/RestrictedHookUnitTest.inc create mode 100644 WordPressVIPMinimum/Tests/Filters/RestrictedHookUnitTest.php diff --git a/WordPress-VIP-Go/ruleset.xml b/WordPress-VIP-Go/ruleset.xml index 0e1f38ff..60a9b946 100644 --- a/WordPress-VIP-Go/ruleset.xml +++ b/WordPress-VIP-Go/ruleset.xml @@ -104,6 +104,10 @@ + + warning + 10 + warning 7 diff --git a/WordPressVIPMinimum/Sniffs/Filters/RestrictedHookSniff.php b/WordPressVIPMinimum/Sniffs/Filters/RestrictedHookSniff.php new file mode 100644 index 00000000..cf2613e1 --- /dev/null +++ b/WordPressVIPMinimum/Sniffs/Filters/RestrictedHookSniff.php @@ -0,0 +1,102 @@ + true, + 'add_action' => true, + ]; + + /** + * List of restricted filter names. + * + * @var array + */ + private $restricted_hooks = [ + 'upload_mimes' => [ + 'error' => 'Please ensure that the mimes being filtered do not include insecure types (e.g. SVG). Manual inspection required.', + 'errorcode' => 'UploadMimes', + ], + ]; + + /** + * Process the parameters of a matched function. + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * @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. + */ + public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + foreach ( $this->restricted_hooks as $restricted_hook => $hook_args ) { + if ( $this->normalize_hook_name_from_parameter( $parameters[1] ) === $restricted_hook ) { + $this->phpcsFile->addWarning( $hook_args['error'], $stackPtr, $hook_args['errorcode'] ); + } + } + } + + /** + * Normalize hook name parameter. + * + * @param array $parameter Array with information about a parameter. + * @return string Normalized hook name. + */ + private function normalize_hook_name_from_parameter( $parameter ) { + // If concatenation is found, build hook name. + $concat_ptr = $this->phpcsFile->findNext( + T_STRING_CONCAT, + $parameter['start'], + $parameter['end'], + false, + null, + true + ); + + if ( $concat_ptr ) { + $hook_name = ''; + for ( $i = $parameter['start'] + 1; $i < $parameter['end']; $i++ ) { + if ( T_CONSTANT_ENCAPSED_STRING === $this->tokens[ $i ]['code'] ) { + $hook_name .= str_replace( [ "'", '"' ], '', $this->tokens[ $i ]['content'] ); + } + } + } else { + $hook_name = $parameter['raw']; + } + + // Remove quotes (double and single), and use lowercase. + return strtolower( str_replace( [ "'", '"' ], '', $hook_name ) ); + } +} diff --git a/WordPressVIPMinimum/Tests/Filters/RestrictedHookUnitTest.inc b/WordPressVIPMinimum/Tests/Filters/RestrictedHookUnitTest.inc new file mode 100644 index 00000000..559fd26a --- /dev/null +++ b/WordPressVIPMinimum/Tests/Filters/RestrictedHookUnitTest.inc @@ -0,0 +1,19 @@ + => + */ + public function getErrorList() { + return []; + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return [ + 7 => 1, + 8 => 1, + 9 => 1, + 10 => 1, + 11 => 1, + 12 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + 16 => 1, + 19 => 1, + ]; + } + +}