mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 14:52:40 +01:00
Add a linter rule for the use of parse_str
Summary: The use of the [[http://php.net/manual/en/function.parse-str.php | parse_str]] method (when called without sepcifying a second parameter) hinders static analysis. Specifically, the `parse_str('...')` behaves similarly to [[http://php.net/manual/en/function.extract.php | extract]]. Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D13857
This commit is contained in:
parent
2e76e2965c
commit
fe8ed2a6f8
5 changed files with 45 additions and 0 deletions
|
@ -185,6 +185,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistPHPOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPOpenTagXHPASTLinterRule.php',
|
'ArcanistPHPOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPOpenTagXHPASTLinterRule.php',
|
||||||
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
|
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
|
||||||
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
|
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
|
||||||
|
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
|
||||||
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
|
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
|
||||||
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
|
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
|
||||||
'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php',
|
'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php',
|
||||||
|
@ -467,6 +468,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistPHPOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistPHPOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
|
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
|
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
|
||||||
'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
|
'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
|
||||||
'ArcanistPhpLinter' => 'ArcanistExternalLinter',
|
'ArcanistPhpLinter' => 'ArcanistExternalLinter',
|
||||||
|
|
5
src/lint/linter/__tests__/xhpast/extract-use.lint-test
Normal file
5
src/lint/linter/__tests__/xhpast/extract-use.lint-test
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
extract();
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:3:1
|
7
src/lint/linter/__tests__/xhpast/parse_str-use.lint-test
Normal file
7
src/lint/linter/__tests__/xhpast/parse_str-use.lint-test
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$params = array();
|
||||||
|
parse_str('foo=bar', $params);
|
||||||
|
parse_str('foo=bar');
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:5:1
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistParseStrUseXHPASTLinterRule
|
||||||
|
extends ArcanistXHPASTLinterRule {
|
||||||
|
|
||||||
|
const ID = 80;
|
||||||
|
|
||||||
|
public function getLintName() {
|
||||||
|
return pht('Questionable Use of %s', 'parse_str()');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(XHPASTNode $root) {
|
||||||
|
$calls = $this->getFunctionCalls($root, array('parse_str'));
|
||||||
|
|
||||||
|
foreach ($calls as $call) {
|
||||||
|
$call_params = $call->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
|
||||||
|
|
||||||
|
if (count($call_params->getChildren()) < 2) {
|
||||||
|
$this->raiseLintAtNode(
|
||||||
|
$call,
|
||||||
|
pht(
|
||||||
|
'Avoid %s unless the second parameter is specified. '.
|
||||||
|
'It is confusing and hinders static analysis.',
|
||||||
|
'parse_str()'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -48,6 +48,8 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
||||||
//
|
//
|
||||||
// TODO: Support functions defined inside other functions which is commonly
|
// TODO: Support functions defined inside other functions which is commonly
|
||||||
// used with anonymous functions.
|
// used with anonymous functions.
|
||||||
|
//
|
||||||
|
// TODO: parse_str() also makes lexical scope unknowable, see D13857.
|
||||||
|
|
||||||
$defs = $root->selectDescendantsOfTypes(array(
|
$defs = $root->selectDescendantsOfTypes(array(
|
||||||
'n_FUNCTION_DECLARATION',
|
'n_FUNCTION_DECLARATION',
|
||||||
|
|
Loading…
Reference in a new issue