How to catch PHP backtick operator usage via PHP_CodeSniffer?
I've studied some "sniffs" from the "Generic" and "Squiz" coding standards that come with CodeSniffer version 1.3, and learned enough to write a few "custom" sniffs to catch some coding anti-patterns which are specific to a PHP project that I'm working on.
But now my boss wants me to use the tool to identify all the places where the code calls exec(), popen(), passthru(), or uses the backtick operator to run an "external" command, and I've hit a snag dealing with the backticks.
The Generic_Sniffs_PHP_ForbiddenFunctionsSniff class which comes with the CodeSniffer 1.3 distribution makes it essentially trivial to identify any calls to a "dangerous function" like exec(), popen(), and passthru(), so that part is easy.
But I cannot see any references to backtick operators in the "stock" sniffs, nor do I see any mention of the backtick operator in any of the CodeSniffer logic itself - although I may be looking开发者_开发问答 in the wrong place (it took me a while to figure out that "->" is really T_OBJECT_OPERATOR, for example).
So my question is this:
Can I use PHP_CodeSniffer to detect backtick operator usage in PHP code, and if so, how?
http://php.net/manual/en/tokens.php
Looks like there's no token for backticks. You should, however, be able to follow the class hierarchy low enough down that you can find a connection point where you can just do strpos or preg_match looking for `. It should mention in the CodeSniffer documentation how to do that, or, like I said, you could follow the Generic_Sniffs_PHP_ForbiddenFunctionsSniff class up to its parent (and up to its parent if necessary) until you find where the actual searching is happening.
Edit: Just looked into the CodeSniffer code, and it appears that it might only support token searching... So it looks like you will have to make a new token.
This example (with most comments stripped out) works with a few simple test cases - no CodeSniffer changes required!
class test_Sniffs_Dangerous_BackTickSniff implements PHP_CodeSniffer_Sniff {public $supportedTokenizers = array('PHP'); public function register() { return array(T_NONE); } public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // generate one error for every pair of backticks: static $reported = array(); $all_tokens = $phpcsFile->getTokens(); if ($all_tokens[$stackPtr]['content'] == '`') { $lno = $all_tokens[$stackPtr]['line']; if (!isset($reported[$lno])) { $reported[$lno] = true; $phpcsFile->addError('Avoid backticks', $stackPtr); } } }
}
As this is what I was after, I'm going to answer my own question. Thanks Corbin, and ircmaxell, for your comments.
精彩评论