1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 23:02:41 +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:
Joshua Spence 2015-08-14 07:44:19 +10:00
parent 2e76e2965c
commit fe8ed2a6f8
5 changed files with 45 additions and 0 deletions

View file

@ -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',

View file

@ -0,0 +1,5 @@
<?php
extract();
~~~~~~~~~~
error:3:1

View file

@ -0,0 +1,7 @@
<?php
$params = array();
parse_str('foo=bar', $params);
parse_str('foo=bar');
~~~~~~~~~~
error:5:1

View file

@ -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()'));
}
}
}
}

View file

@ -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',