diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -41,7 +41,19 @@ "exclude": "(resources/spelling/.*\\.json$)" }, "text": { - "type": "text" + "type": "text", + "exclude": [ + "(^\\.arclint$)" + ] + }, + "text-without-length": { + "type": "text", + "severity": { + "3": "disabled" + }, + "include": [ + "(^\\.arclint$)" + ] }, "xhpast": { "type": "xhpast", @@ -50,6 +62,9 @@ "16": "advice", "34": "error" }, + "xhpast.blacklisted.function": { + "eval": "The eval() function should be avoided. It is potentially unsafe and makes debugging more difficult." + }, "xhpast.php-version": "5.2.3", "xhpast.php-version.windows": "5.3.0" } diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php --- a/src/lint/linter/ArcanistXHPASTLinter.php +++ b/src/lint/linter/ArcanistXHPASTLinter.php @@ -50,7 +50,9 @@ const LINT_ARRAY_SEPARATOR = 48; const LINT_CONSTRUCTOR_PARENTHESES = 49; const LINT_DUPLICATE_SWITCH_CASE = 50; + const LINT_BLACKLISTED_FUNCTION = 50; + private $blacklistedFunctions = array(); private $naminghook; private $switchhook; private $version; @@ -111,6 +113,7 @@ self::LINT_ARRAY_SEPARATOR => 'Array Separator', self::LINT_CONSTRUCTOR_PARENTHESES => 'Constructor Parentheses', self::LINT_DUPLICATE_SWITCH_CASE => 'Duplicate Case Statements', + self::LINT_BLACKLISTED_FUNCTION => 'Use of Blacklisted Function', ); } @@ -157,6 +160,10 @@ public function getLinterConfigurationOptions() { return parent::getLinterConfigurationOptions() + array( + 'xhpast.blacklisted.function' => array( + 'type' => 'optional map', + 'help' => pht('Blacklisted functions which should not be used.'), + ), 'xhpast.naminghook' => array( 'type' => 'optional string', 'help' => pht( @@ -182,6 +189,9 @@ public function setLinterConfigurationValue($key, $value) { switch ($key) { + case 'xhpast.blacklisted.function': + $this->blacklistedFunctions = $value; + return; case 'xhpast.naminghook': $this->naminghook = $value; return; @@ -201,7 +211,7 @@ public function getVersion() { // The version number should be incremented whenever a new rule is added. - return '12'; + return '13'; } protected function resolveFuture($path, Future $future) { @@ -274,6 +284,7 @@ 'lintArraySeparator' => self::LINT_ARRAY_SEPARATOR, 'lintConstructorParentheses' => self::LINT_CONSTRUCTOR_PARENTHESES, 'lintSwitchStatements' => self::LINT_DUPLICATE_SWITCH_CASE, + 'lintBlacklistedFunction' => self::LINT_BLACKLISTED_FUNCTION, ); foreach ($method_codes as $method => $codes) { @@ -2969,6 +2980,24 @@ } } + private function lintBlacklistedFunction(XHPASTNode $root) { + $calls = $root->selectDescendantsOfType('n_FUNCTION_CALL'); + + foreach ($calls as $call) { + $node = $call->getChildByIndex(0); + $name = $node->getConcreteString(); + + $reason = idx($this->blacklistedFunctions, $name); + + if ($reason) { + $this->raiseLintAtNode( + $node, + self::LINT_BLACKLISTED_FUNCTION, + $reason); + } + } + } + public function getSuperGlobalNames() { return array( '$GLOBALS', diff --git a/src/lint/linter/__tests__/xhpast/blacklisted.lint-test b/src/lint/linter/__tests__/xhpast/blacklisted.lint-test new file mode 100644 --- /dev/null +++ b/src/lint/linter/__tests__/xhpast/blacklisted.lint-test @@ -0,0 +1,7 @@ +