Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GlobalVariablesOverride: detect variable overrides in global namespace #1457

Merged

Conversation

jrfnl
Copy link
Member

@jrfnl jrfnl commented Aug 19, 2018

This PR changes the GlobalVariablesOverride sniff to always check for variable overrides in the global namespace, independently of there being a global statement or not.

While this may throw false positives for theme template files/ plugin view files which are include-ed from within a function and therefore scoped to that function, there is no guarantee that the file will always be included from within an function in another file, so using the same variable name as used by WP itself, would still be bad practice.

All the same, I've added a public treat_files_as_scoped property which when set to true from within a custom ruleset, basically reverts the sniff back to the old behaviour.
The default is false and setting this property to true should be discouraged.

If - in the future - PHPCS would allow limiting the effect of // phpcs:set annotations to the file in which the annotation is used, that annotation could be used in the file header for view/template files to revert to the old behaviour just and only for those particular files. See upstream feature request squizlabs/PHP_CodeSniffer#2126 for more information.

Additional notes/fixes:

  • Move the is_foreach_as() method from the PrefixAllGlobals class to the Sniff base class so it can also be used by this sniff.
  • Made the sniff more efficient by checking for test classes early and skipping over them completely.
  • Made the sniff more efficient by checking early for whitelist comments when examining T_VARIABLE tokens.
  • Bug fix: when examining a global statement, nested funcions/closures/classes should always be skipped. Previously, this was only done when the global statement was found in the global namespace.
  • Don't throw errors for default values for function parameters in function declarations when the function parameter name would be shadowing a WP global variable or the PHP $GLOBALS variable.
  • Don't throw errors for class properties.
  • Improved the error message when an assignment to $GLOBALS is found
    Previously, the error message would just show the rather non-descript $GLOBALS, now it will show $GLOBALS['array_key'].

See the individual commits for more detailed information.

Fixes #1395

To do once the PR is merged:

  • Add information to the wiki about the new customizable property.

jrfnl added 9 commits August 19, 2018 01:39
... and allow for multiple test case files in the test provider file.
* Register class/trait tokens.
* Bow out earlier if a class/trait token turns out to translate to a test class.
* Skip over the rest of that class.
If the token being examined is a `T_VARIABLE` token and has a whitelist comment, the sniff can bow out before examining the token in detail.

Includes splitting the `maybe_add_error()` method up to prevent checking twice for a whitelist comment.

For the `T_GLOBAL` token this is not possible as the whitelist comment will not be on the line with the `$stackPtr` pointing to the `global` keyword.
… scope

* Minor simplification of how the `$search` array is gathered.
* Search only within the function scope.
* Skip over nested functions/closures/classes.
* Minor code changes to lower the nesting levels.
…scope

Examine variables found in the global scope and always examine the `$GLOBALS` variable independently of scope.

* Minor efficiency fix when checking the array key of a `$GLOBALS` variable - no need to walk the token array twice.
* Error prevention for when the `$GLOBALS` array key would not contain a `T_CONSTANT_ENCAPSED_STRING` token.
* Don't throw errors for default values for function parameters in function declarations.
* Don't throw errors for class properties.
By setting the `treat_files_as_scoped` property to `true`, the sniff will regard each file as being included from with a function, making it scoped to the function holding the `include` statement.

This basically allows for the sniff to revert back to the original behaviour of only examining variables in the global scope if a `global` statement had been found or if the variable used was `$GLOBALS`.
… to $GLOBALS is found

Previously, the error message would just show the rather non-descript `$GLOBALS`, now it will show `$GLOBALS['array_key']`.
@jrfnl
Copy link
Member Author

jrfnl commented Aug 25, 2018

Anyone have an opinion on this ?

@jrfnl
Copy link
Member Author

jrfnl commented Sep 3, 2018

@WordPress-Coding-Standards/wpcs-admins Anything I can do to move this PR forward ? It is a significant change, so a second review (and if deemed acceptable: approval), would be appreciated.

@JDGrimes JDGrimes merged commit 784fefe into develop Sep 7, 2018
@JDGrimes JDGrimes deleted the feature/1395-detect-variable-overrides-in-global-namespace branch September 7, 2018 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GlobalVariableOverride doesn't actually detect override in the global namespace
3 participants