Page MenuHomePhabricator

D13857.diff
No OneTemporary

D13857.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -185,6 +185,7 @@
'ArcanistPHPOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPOpenTagXHPASTLinterRule.php',
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
+ 'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php',
@@ -467,6 +468,7 @@
'ArcanistPHPOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
'ArcanistPhpLinter' => 'ArcanistExternalLinter',
diff --git a/src/lint/linter/__tests__/xhpast/extract-use.lint-test b/src/lint/linter/__tests__/xhpast/extract-use.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/extract-use.lint-test
@@ -0,0 +1,5 @@
+<?php
+
+extract();
+~~~~~~~~~~
+error:3:1
diff --git a/src/lint/linter/__tests__/xhpast/parse_str-use.lint-test b/src/lint/linter/__tests__/xhpast/parse_str-use.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/parse_str-use.lint-test
@@ -0,0 +1,7 @@
+<?php
+
+$params = array();
+parse_str('foo=bar', $params);
+parse_str('foo=bar');
+~~~~~~~~~~
+error:5:1
diff --git a/src/lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php
@@ -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()'));
+ }
+ }
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/ArcanistUndeclaredVariableXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistUndeclaredVariableXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/rules/ArcanistUndeclaredVariableXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/rules/ArcanistUndeclaredVariableXHPASTLinterRule.php
@@ -48,6 +48,8 @@
//
// TODO: Support functions defined inside other functions which is commonly
// used with anonymous functions.
+ //
+ // TODO: parse_str() also makes lexical scope unknowable, see D13857.
$defs = $root->selectDescendantsOfTypes(array(
'n_FUNCTION_DECLARATION',

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 15, 9:14 PM (1 w, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7703796
Default Alt Text
D13857.diff (3 KB)

Event Timeline