diff --git a/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php b/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php new file mode 100644 index 0000000000..ccdebda307 --- /dev/null +++ b/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php @@ -0,0 +1,62 @@ + array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) + * + * @return array + */ + public function getGroups() { + return array( + 'error_log' => array( + 'type' => 'error', + 'message' => '%s Debug code is not to be used in Production', + 'functions' => array( + 'error_log', + 'var_dump', + 'var_export', + 'print_r', + 'trigger_error', + 'set_error_handler', + 'debug_backtrace', + 'debug_print_backtrace', + 'wp_debug_backtrace_summary', + ), + ), + + 'prevent_path_disclosure' => array( + 'type' => 'error', + 'message' => '%s is prohibited as it can lead to full path disclosure.', + 'functions' => array( + 'error_reporting', + 'phpinfo', + ), + ), + + ); + } // end getGroups() + +} // end class diff --git a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php index 713f41693c..3469aa453f 100644 --- a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php @@ -7,65 +7,68 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'Generic_Sniffs_PHP_ForbiddenFunctionsSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class Generic_Sniffs_PHP_ForbiddenFunctionsSniff not found' ); -} - /** - * Discourages the use of various functions and suggests (WordPress) alternatives. + * Discourages the use of various functions and suggests alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.1.0 * @since 0.10.0 The checks for the POSIX functions have been replaced by the stand-alone * sniff WordPress_Sniffs_PHP_POSIXFunctionsSniff. + * @since 0.11.0 The checks for the PHP development functions have been replaced by the + * stand-alone sniff WordPress_Sniffs_PHP_DevelopmentFunctionsSniff. + * The checks for the PHP deprecated functions have been replaced by the + * stand-alone sniff WordPress_Sniffs_PHP_DeprecatedFunctionsSniff. + * The checks for the WP deprecated functions have been replaced by the + * stand-alone sniff WordPress_Sniffs_WP_DeprecatedFunctionsSniff. + * The checks for the PHP functions which have a WP alternative has been replaced + * by the stand-alone sniff WordPress_Sniffs_WP_AlternativeFunctionsSniff. + * The checks for the WP discouraged functions have been replaced by the + * stand-alone sniff WordPress_Sniffs_WP_DiscouragedFunctionsSniff. */ -class WordPress_Sniffs_PHP_DiscouragedFunctionsSniff extends Generic_Sniffs_PHP_ForbiddenFunctionsSniff { +class WordPress_Sniffs_PHP_DiscouragedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { /** - * A list of forbidden functions with their alternatives. + * Groups of functions to discourage. * - * The value is NULL if no alternative exists. I.e. the - * function should just not be used. + * Example: groups => array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) * - * @var array(string => string|null) + * @return array */ - public $forbiddenFunctions = array( - // Development. - 'print_r' => null, - 'debug_print_backtrace' => null, - 'var_dump' => null, - 'var_export' => null, - - // Discouraged. - 'json_encode' => 'wp_json_encode', + public function getGroups() { + return array( + 'create_function' => array( + 'type' => 'warning', + 'message' => '%s is discouraged, please use anonymous functions instead.', + 'functions' => array( + 'create_function', + ), + ), - // WordPress deprecated. - 'find_base_dir' => 'WP_Filesystem::abspath', - 'get_base_dir' => 'WP_Filesystem::abspath', - 'dropdown_categories' => 'wp_link_category_checklist', - 'dropdown_link_categories' => 'wp_link_category_checklist', - 'get_link' => 'get_bookmark', - 'get_catname' => 'get_cat_name', - 'register_globals' => null, - 'wp_setcookie' => 'wp_set_auth_cookie', - 'wp_get_cookie_login' => null, - 'wp_login' => 'wp_signon', - 'get_the_attachment_link' => 'wp_get_attachment_link', - 'get_attachment_icon_src' => 'wp_get_attachment_image_src', - 'get_attachment_icon' => 'wp_get_attachment_image', - 'get_attachment_innerHTML' => 'wp_get_attachment_image', + 'serialize' => array( + 'type' => 'warning', + 'message' => '%s Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data.', + 'functions' => array( + 'serialize', + 'unserialize', + ), + ), - // WordPress discouraged. - 'query_posts' => 'WP_Query', - 'wp_reset_query' => 'wp_reset_postdata', - ); + 'urlencode' => array( + 'type' => 'warning', + 'message' => '%s urlencode should only be used when dealing with legacy applications rawurlencode should now de used instead. See http://php.net/manual/en/function.rawurlencode.php and http://www.faqs.org/rfcs/rfc3986.html', + 'functions' => array( + 'urlencode', + ), + ), - /** - * If true, an error will be thrown; otherwise a warning. - * - * @var bool - */ - public $error = false; + ); + } // end getGroups() } // End class. diff --git a/WordPress/Sniffs/PHP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/PHP/RestrictedFunctionsSniff.php new file mode 100644 index 0000000000..3538147333 --- /dev/null +++ b/WordPress/Sniffs/PHP/RestrictedFunctionsSniff.php @@ -0,0 +1,45 @@ + array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) + * + * @return array + */ + public function getGroups() { + return array( + 'eval' => array( + 'type' => 'error', + 'message' => '%s is prohibited, please use anonymous functions instead.', + 'functions' => array( + 'eval', + ), + ), + + ); + } // end getGroups() + +} // End class. diff --git a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php index 3763047d05..37ae9498de 100644 --- a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php @@ -16,6 +16,15 @@ * @since 0.10.0 The checks for `extract()` and the POSIX functions have been replaced by * the stand-alone sniffs WordPress_Sniffs_Functions_DontExtractSniff and * WordPress_Sniffs_PHP_POSIXFunctionsSniff respectively. + * @since 0.11.0 The checks for `create_function()`, `serialize()`/`unserialize()` and + * `urlencode` have been moved to the stand-alone sniff + * WordPress_Sniffs_PHP_DiscouragedFunctionsSniff. + * The checks for `parse_url()` hs been moved to the stand-alone sniff + * WordPress_Sniffs_WP_AlternativesFunctionsSniff. + * The checks for `eval()` hs been moved to the stand-alone sniff + * WordPress_Sniffs_PHP_RestrictedFunctionsSniff. + * The checks for PHP developer functions, `error_reporting` and `phpinfo`have been + * moved to the stand-alone sniff WordPress_Sniffs_PHP_DevelopmentFunctionsSniff. */ class WordPress_Sniffs_VIP_RestrictedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { @@ -41,24 +50,6 @@ public function getGroups() { 'functions' => array( 'switch_to_blog' ), ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#eval-and-create_function - 'create_function' => array( - 'type' => 'warning', - 'message' => '%s is discouraged, please use Anonymous functions instead.', - 'functions' => array( - 'create_function', - ), - ), - - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#eval-and-create_function - 'eval' => array( - 'type' => 'error', - 'message' => '%s is prohibited, please use Anonymous functions instead.', - 'functions' => array( - 'eval', - ), - ), - 'file_get_contents' => array( 'type' => 'warning', 'message' => '%s is highly discouraged, please use wpcom_vip_file_get_contents() instead.', @@ -234,15 +225,6 @@ public function getGroups() { ), ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#use-wp_parse_url-instead-of-parse_url - 'parse_url' => array( - 'type' => 'warning', - 'message' => '%s is discouraged due to a lack for backwards-compatibility in PHP versions; please use wp_parse_url() instead.', - 'functions' => array( - 'parse_url', - ), - ), - 'get_intermediate_image_sizes' => array( 'type' => 'error', 'message' => 'Intermediate images do not exist on the VIP platform, and thus get_intermediate_image_sizes() returns an empty array() on the platform. This behavior is intentional to prevent WordPress from generating multiple thumbnails when images are uploaded.', @@ -251,29 +233,6 @@ public function getGroups() { ), ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#serializing-data - 'serialize' => array( - 'type' => 'warning', - 'message' => '%s Serialized data has known vulnerability problems with Object Injection. JSON is generally a better approach for serializing data.', - 'functions' => array( - 'serialize', - 'unserialize', - ), - ), - - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#commented-out-code-debug-code-or-output - 'error_log' => array( - 'type' => 'error', - 'message' => '%s Debug code is not allowed on VIP Production', - 'functions' => array( - 'error_log', - 'var_dump', - 'print_r', - 'trigger_error', - 'set_error_handler', - ), - ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#use-wp_safe_redirect-instead-of-wp_redirect 'wp_redirect' => array( 'type' => 'warning', @@ -292,15 +251,6 @@ public function getGroups() { ), ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#encoding-values-used-when-creating-a-url-or-passed-to-add_query_arg - 'urlencode' => array( - 'type' => 'warning', - 'message' => '%s should only be used when dealing with legacy applications, rawurlencode() should now be used instead. See http://php.net/manual/en/function.rawurlencode.php and http://www.faqs.org/rfcs/rfc3986.html', - 'functions' => array( - 'urlencode', - ), - ), - // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#settings-alteration 'runtime_configuration' => array( 'type' => 'error', @@ -320,15 +270,6 @@ public function getGroups() { ), ), - 'prevent_path_disclosure' => array( - 'type' => 'error', - 'message' => '%s is prohibited as it can lead to full path disclosure.', - 'functions' => array( - 'error_reporting', - 'phpinfo', - ), - ), - ); } // End getGroups(). diff --git a/WordPress/Sniffs/WP/AlternativesFunctionsSniff.php b/WordPress/Sniffs/WP/AlternativesFunctionsSniff.php new file mode 100644 index 0000000000..078d43e1dc --- /dev/null +++ b/WordPress/Sniffs/WP/AlternativesFunctionsSniff.php @@ -0,0 +1,69 @@ + array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) + * + * @return array + */ + public function getGroups() { + return array( + 'curl' => array( + 'type' => 'warning', + 'message' => 'Using cURL functions is highly discouraged. Use wp_remote_get() instead.', + 'functions' => array( + 'curl_*', + ), + ), + + 'parse_url' => array( + 'type' => 'warning', + 'message' => '%s is discouraged due to a lack for backwards-compatibility in PHP versions; use wp_parse_url() instead.', + 'functions' => array( + 'parse_url', + ), + ), + + 'json_encode' => array( + 'type' => 'warning', + 'message' => '%s is discouraged. Use wp_json_encode() instead.', + 'functions' => array( + 'json_encode', + ), + ), + + 'file_get_contents' => array( + 'type' => 'warning', + 'message' => '%s is discouraged. Use wp_remote_get() instead.', + 'functions' => array( + 'file_get_contents', + ), + ), + + ); + } // end getGroups() + +} // end class diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php new file mode 100644 index 0000000000..10d7377e5c --- /dev/null +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -0,0 +1,53 @@ + array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) + * + * @return array + */ + public function getGroups() { + return array( + 'get_postdata' => array( + 'type' => 'error', + 'message' => '%s has been deprecated since WordPress 1.5.1. Use get_post() instead.', + 'functions' => array( + 'get_postdata', + ), + ), + + 'start_wp' => array( + 'type' => 'error', + 'message' => '%s has been deprecated since WordPress 1.5 Use the Loop instead.', + 'functions' => array( + 'get_postdata', + ), + ), + + ); + } // end getGroups() + +} // end class diff --git a/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php b/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php new file mode 100644 index 0000000000..8f93bd5863 --- /dev/null +++ b/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php @@ -0,0 +1,53 @@ + array( + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'eval', 'create_function' ), + * ) + * ) + * + * @return array + */ + public function getGroups() { + return array( + 'query_posts' => array( + 'type' => 'warning', + 'message' => '%s is discouraged. Use WP_Query instead.', + 'functions' => array( + 'query_posts', + ), + ), + + 'wp_reset_query' => array( + 'type' => 'warning', + 'message' => '%s is discouraged. Use the wp_reset_postdata instead.', + 'functions' => array( + 'wp_reset_query', + ), + ), + + ); + } // end getGroups() + +} // end class diff --git a/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.inc b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.inc new file mode 100644 index 0000000000..1c8a1ced75 --- /dev/null +++ b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.inc @@ -0,0 +1,16 @@ + => + */ + public function getErrorList() { + return array( + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 9 => 1, + 10 => 1, + 11 => 1, + 13 => 1, + 15 => 1, + 16 => 1, + ); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. diff --git a/WordPress/Tests/PHP/DiscouragedFunctionsUnitTest.inc b/WordPress/Tests/PHP/DiscouragedFunctionsUnitTest.inc index b86c3f0377..d35ab123f0 100644 --- a/WordPress/Tests/PHP/DiscouragedFunctionsUnitTest.inc +++ b/WordPress/Tests/PHP/DiscouragedFunctionsUnitTest.inc @@ -1,54 +1,11 @@ 1, + 7 => 1, 8 => 1, - 9 => 1, - 15 => 1, - 17 => 1, - 19 => 1, - 21 => 1, - 23 => 1, - 25 => 1, - 27 => 1, - 29 => 1, - 31 => 1, - 33 => 1, - 35 => 1, - 37 => 1, - 39 => 1, - 45 => 1, - 47 => 1, - 52 => 1, - 54 => 1, + 10 => 1, ); } diff --git a/WordPress/Tests/PHP/RestrictedFunctionsUnitTest.inc b/WordPress/Tests/PHP/RestrictedFunctionsUnitTest.inc new file mode 100644 index 0000000000..7e21dbb4e7 --- /dev/null +++ b/WordPress/Tests/PHP/RestrictedFunctionsUnitTest.inc @@ -0,0 +1,3 @@ + => + */ + public function getErrorList() { + return array( + 3 => 1, + ); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc index 4be591b00d..ceeb1b1de0 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc @@ -1,24 +1,20 @@ add_role(); // Ok. $y = Bar::add_role(); // Ok. \SomeNamespace\add_role(); // Ok. -\add_role(); // Bad. +\add_role(); // Error. -get_term_link( $term ); // Bad. +get_term_link( $term ); // Error. -get_page_by_path( $path ); // Bad. +get_page_by_path( $path ); // Error. -get_page_by_title( $page_title ); // Bad. +get_page_by_title( $page_title ); // Error. -get_term_by( $field, $value, $taxonomy ); // Bad. +get_term_by( $field, $value, $taxonomy ); // Error. -get_category_by_slug( $slug ); // Bad. +get_category_by_slug( $slug ); // Error. -url_to_postid( $url ); // Bad. +url_to_postid( $url ); // Error. -attachment_url_to_postid( $url ); // Bad. +attachment_url_to_postid( $url ); // Error. wpcom_vip_attachment_url_to_postid( $url ); // Ok. get_tag_link(); // Error. @@ -69,7 +65,6 @@ wp_old_slug_redirect(); // Error. get_adjacent_post(); // Error. get_previous_post(); // Error. get_next_post(); // Error. -parse_url( 'http://example.com/' ); // Warning. dl(); // Error. error_reporting(); // Error. @@ -82,24 +77,14 @@ apache_setenv(); // Error. putenv(); // Error. set_include_path(); // Error. restore_include_path(); // Error. -phpinfo(); // Error. -PHPINFO(); // Error. -CURL_getinfo(); // Error. +CURL_getinfo(); // Warning. curlyhair(); // Ok. get_previous_post_link(); // Error. get_next_post_link(); // Error. get_intermediate_image_sizes(); // Error. -serialize(); // Warning. -unserialize(); // Warning. -error_log(); // Error. -var_dump(); // Error. -print_r(); // Error. -trigger_error(); // Error. -set_error_handler(); // Error. + wp_redirect(); // Warning. wp_is_mobile(); // Error. -urlencode(); // Warning. -rawurlencode(); // Ok. diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php index 831cb9a122..26572521f9 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php @@ -23,54 +23,46 @@ class WordPress_Tests_VIP_RestrictedFunctionsUnitTest extends AbstractSniffUnitT public function getErrorList() { return array( 3 => 1, - 5 => 1, - 21 => 1, - 34 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, + 17 => 1, + 30 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, + 32 => 1, + 34 => 1, 36 => 1, 38 => 1, 40 => 1, 42 => 1, 44 => 1, 46 => 1, - 48 => 1, + 49 => 1, 50 => 1, + 51 => 1, + 52 => 1, 53 => 1, - 54 => 1, - 55 => 1, - 56 => 1, - 57 => 1, + 58 => 1, + 59 => 1, + 60 => 1, + 61 => 1, 62 => 1, 63 => 1, 64 => 1, 65 => 1, 66 => 1, 67 => 1, - 68 => 1, 69 => 1, 70 => 1, 71 => 1, + 72 => 1, + 73 => 1, 74 => 1, - 75 => 2, + 75 => 1, 76 => 1, 77 => 1, 78 => 1, 79 => 1, - 80 => 1, - 81 => 1, - 82 => 1, - 83 => 1, - 84 => 1, 85 => 1, + 86 => 1, 87 => 1, - 92 => 1, - 93 => 1, - 94 => 1, - 97 => 1, - 98 => 1, - 99 => 1, - 100 => 1, - 101 => 1, - 103 => 1, + 90 => 1, ); } // End getErrorList(). @@ -82,21 +74,16 @@ public function getErrorList() { */ public function getWarningList() { return array( + 5 => 1, 7 => 1, - 9 => 1, + 9 => 1, 11 => 1, 13 => 1, - 15 => 1, - 17 => 1, - 58 => 1, - 59 => 1, - 61 => 1, - 72 => 1, - 88 => 1, - 95 => 1, - 96 => 1, - 102 => 1, - 104 => 1, + 54 => 1, + 55 => 1, + 57 => 1, + 81 => 1, + 89 => 1, ); } diff --git a/WordPress/Tests/WP/AlternativesFunctionsUnitTest.inc b/WordPress/Tests/WP/AlternativesFunctionsUnitTest.inc new file mode 100644 index 0000000000..5ccb8af9dd --- /dev/null +++ b/WordPress/Tests/WP/AlternativesFunctionsUnitTest.inc @@ -0,0 +1,12 @@ + => + */ + public function getErrorList() { + return array(); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 3 => 1, + 4 => 1, + 5 => 1, + 8 => 1, + 10 => 1, + 12 => 1, + ); + + } + +} // End class. diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc new file mode 100644 index 0000000000..8a5b16b1bf --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -0,0 +1,30 @@ + => + */ + public function getErrorList() { + return array(); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 3 => 1, + 5 => 1, + ); + + } + +} // End class.