Records a warning against a specific token in the file.
public addWarning ( string $warning, integer $stackPtr, string $code = '', array $data = [], integer $severity, boolean $fixable = false ) : boolean | ||
$warning | string | The error message. |
$stackPtr | integer | The stack position where the error occurred. |
$code | string | A violation code unique to the sniff message. |
$data | array | Replacements for the warning message. |
$severity | integer | The severity level for this warning. A value of 0 will be converted into the default severity level. |
$fixable | boolean | Can the warning be fixed by the sniff? |
return | boolean |
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $utils = Security_Sniffs_UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); if (preg_match('/<|>/', $tokens[$stackPtr]['content'])) { $end = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1); $next = $stackPtr; while ($next && ($next = $phpcsFile->findNext(array_merge(array(T_STRING_CONCAT), PHP_CodeSniffer_Tokens::$emptyTokens), $next + 1, $end, true))) { // Next token will be checked with this sniff, no need to go further if (in_array($tokens[$next]['code'], $this->register())) { return; } if ($next && !in_array($tokens[$next]['content'], $utils::getXSSMitigationFunctions())) { if ($utils::is_direct_user_input($tokens[$next]['content'])) { $phpcsFile->addError('HTML construction with direct user input ' . $tokens[$next]['content'] . ' detected.', $stackPtr, 'D7XSSHTMLConstructErr'); } elseif (PHP_CodeSniffer::getConfigData('ParanoiaMode') && !in_array($tokens[$next]['code'], array_merge(array(T_INLINE_ELSE, T_COMMA), PHP_CodeSniffer_Tokens::$booleanOperators))) { if ($tokens[$next]['code'] == T_CLOSE_PARENTHESIS) { $f = $phpcsFile->findPrevious(T_STRING, $next); if ($f) { $phpcsFile->addWarning('HTML construction with ' . $tokens[$f]['content'] . '() detected.', $stackPtr, 'D7XSSHTMLConstructWarnF'); } } else { $phpcsFile->addWarning('HTML construction with ' . $tokens[$next]['content'] . ' detected.', $stackPtr, 'D7XSSHTMLConstructWarn'); } } } $next = $phpcsFile->findNext(T_STRING_CONCAT, $next + 1, $end); } } }
/** * Processes this test, when one of its tokens is encountered. * * Ensures that early returns are not followed by else. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param integer $stackPtr The position of the current token in the * stack passed in $tokens. * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $nextToken = $phpcsFile->findNext(T_CLOSE_CURLY_BRACKET, $stackPtr + 1); if (!$nextToken) { return; } $tokenInfo = $tokens[$nextToken]; if ($tokenInfo['bracket_opener'] >= $stackPtr) { return; } $nextToken = $phpcsFile->findNext(T_WHITESPACE, $nextToken + 1, null, true); if (!$nextToken) { return; } if ($tokens[$nextToken]['code'] === T_ELSEIF) { $warning = 'The ELSEIF after an early return is not always necessary and can probably be simplified.'; $phpcsFile->addWarning($warning, $stackPtr, 'Warning'); } if ($tokens[$nextToken]['code'] !== T_ELSE) { return; } $warning = 'The ELSE after an early return is not necessary and should be simplified.'; $phpcsFile->addWarning($warning, $stackPtr, 'Warning'); }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $utils = Security_Sniffs_UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); if (in_array($tokens[$stackPtr]['content'], $utils::getFilesystemFunctions())) { if ($tokens[$stackPtr]['content'] == 'symlink') { $phpcsFile->addWarning('Allowing symlink() while open_basedir is used is actually a security risk. Disabled by default in Suhosin >= 0.9.6', $stackPtr, 'WarnSymlink'); } $s = $stackPtr + 1; $opener = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true); if (!$opener) { // No opener found, so it's probably not a function call if (PHP_CodeSniffer::getConfigData('ParanoiaMode')) { $phpcsFile->addWarning('Filesystem function ' . $tokens[$stackPtr]['content'] . ' used but not as a function', $stackPtr, 'WarnWeirdFilesystem'); } return; } $closer = $tokens[$opener]['parenthesis_closer']; $s = $phpcsFile->findNext(array_merge(PHP_CodeSniffer_Tokens::$emptyTokens, PHP_CodeSniffer_Tokens::$bracketTokens, Security_Sniffs_Utils::$staticTokens), $s, $closer, true); if ($s) { $msg = 'Filesystem function ' . $tokens[$stackPtr]['content'] . '() detected with dynamic parameter'; if ($utils::is_token_user_input($tokens[$s])) { $phpcsFile->addError($msg . ' directly from user input', $stackPtr, 'ErrFilesystem'); } else { $phpcsFile->addWarning($msg, $stackPtr, 'WarnFilesystem'); } } } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $utils = Security_Sniffs_UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] == 'preg_replace') { $s = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr); $closer = $tokens[$s]['parenthesis_closer']; $s = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $s + 1, $closer, true); if ($tokens[$s]['code'] == T_CONSTANT_ENCAPSED_STRING) { $pattern = $tokens[$s]['content']; if (substr($pattern, 1, 1) === '/') { // $pattern is a regex if (preg_match('/(\\/|\\))\\w*e\\w*"$/', $pattern)) { $phpcsFile->addWarning("Usage of preg_replace with /e modifier is not recommended.", $stackPtr, 'PregReplaceE'); $s = $phpcsFile->findNext(array(T_COMMA, T_WHITESPACE, T_COMMENT, T_DOC_COMMENT), $s + 1, $closer, true); if ($utils::is_token_user_input($tokens[$s])) { $phpcsFile->addError("User input and /e modifier found in preg_replace, remote code execution possible.", $stackPtr, 'PregReplaceUserInputE'); } } } else { $phpcsFile->addWarning("Weird usage of preg_replace, please check manually for /e modifier.", $stackPtr, 'PregReplaceWeird'); } } elseif ($tokens[$s]['code'] == T_VARIABLE && $utils::is_token_user_input($tokens[$s])) { $phpcsFile->addError("User input found in preg_replace, /e modifier could be used for malicious intent.", $stackPtr, 'PregReplaceUserInput'); } else { $phpcsFile->addWarning("Dynamic usage of preg_replace, please check manually for /e modifier or user input.", $stackPtr, 'PregReplaceDyn'); } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $varname = ltrim($tokens[$stackPtr]['content'], '$'); // Ignore PHP vars $keywords = array('_SERVER', '_GET', '_POST', '_REQUEST', '_SESSION', '_ENV', '_COOKIE', '_FILES', '_MODULE', 'GLOBALS'); if (in_array($varname, $keywords)) { return; } // Check if variable name is valid if (!in_array($varname, $this->exceptions) && !preg_match('#^[a-z][a-z0-9]*(_[a-z0-9]+)*$#', $varname)) { $error = 'Variable "%s" have not right syntax. Should be : "%s"'; $phpcsFile->addWarning($error, $stackPtr, 'VariableNameNotValid', array('$' . $varname, '$' . $this->makeRealName($varname))); } // Now check if there is an object member after the variable $next = $phpcsFile->findNext(array(T_WHITESPACE), $stackPtr + 1, null, true); if ($tokens[$next]['code'] === T_OBJECT_OPERATOR) { $nextMember = $phpcsFile->findNext(array(T_WHITESPACE), $next + 1, null, true); if ($tokens[$nextMember]['code'] === T_STRING) { // Check if this is not a function $nextBracket = $objOperator = $phpcsFile->findNext(array(T_WHITESPACE), $nextMember + 1, null, true); if ($tokens[$nextBracket]['code'] !== T_OPEN_PARENTHESIS) { $membername = $tokens[$nextMember]['content']; if (!in_array($membername, $this->exceptions) && !preg_match('#^[_a-z][a-z0-9]*(_[a-z0-9]+)*$#', $membername)) { $error = 'Variable "%s" have not right syntax. Should be: "%s"'; $phpcsFile->addWarning($error, $stackPtr, 'VariableNameNotValid', array('->' . $membername, '->' . $this->makeRealName($membername))); } } } } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $utils = Security_Sniffs_UtilsFactory::getInstance(); $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] == "'#value'" || $tokens[$stackPtr]['content'] == '"#value"') { $closer = $phpcsFile->findNext(T_SEMICOLON, $stackPtr); $next = $phpcsFile->findNext(array_merge(PHP_CodeSniffer_Tokens::$bracketTokens, PHP_CodeSniffer_Tokens::$emptyTokens, PHP_CodeSniffer_Tokens::$assignmentTokens), $stackPtr + 1, $closer + 1, true); if ($next == $closer && $tokens[$next]['code'] == T_SEMICOLON) { // Case of $label = $element['#value']; $next = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$assignmentTokens, $next); $next = $phpcsFile->findPrevious(T_VARIABLE, $next); $phpcsFile->addWarning('Potential XSS found with #value on ' . $tokens[$next]['content'], $next, 'D7XSSWarFormValue'); } elseif ($next && $utils::is_token_user_input($tokens[$next])) { $phpcsFile->addError('XSS found with #value on ' . $tokens[$next]['content'], $next, 'D7XSSErrFormValue'); } elseif ($next && PHP_CodeSniffer::getConfigData('ParanoiaMode')) { if (in_array($tokens[$next]['content'], $utils::getXSSMitigationFunctions())) { $n = $phpcsFile->findNext($utils::getVariableTokens(), $next + 1, $closer); if ($n) { $phpcsFile->addWarning('Potential XSS found with #value on ' . $tokens[$n]['content'], $n, 'D7XSSWarFormValue'); } } else { $phpcsFile->addWarning('Potential XSS found with #value on ' . $tokens[$next]['content'], $next, 'D7XSSWarFormValue'); } } } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($argument === false) { $error = 'Empty calls to t() are not allowed'; $phpcsFile->addError($error, $stackPtr, 'EmptyT'); return; } if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a translatable string literal. return; } $concatFound = $phpcsFile->findNext(T_STRING_CONCAT, $argument['start'], $argument['end']); if ($concatFound !== false) { $error = 'Concatenating translatable strings is not allowed, use placeholders instead and only one string literal'; $phpcsFile->addError($error, $concatFound, 'Concat'); } $string = $tokens[$argument['start']]['content']; // Check if there is a backslash escaped single quote in the string and // if the string makes use of double quotes. if ($string[0] === "'" && strpos($string, "\\'") !== false && strpos($string, '"') === false) { $warn = 'Avoid backslash escaping in translatable strings when possible, use "" quotes instead'; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashSingleQuote'); return; } if ($string[0] === '"' && strpos($string, '\\"') !== false && strpos($string, "'") === false) { $warn = "Avoid backslash escaping in translatable strings when possible, use '' quotes instead"; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashDoubleQuote'); } }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $error = 'Return statements should have a blank line prior to it.'; $prevLineToken = null; for ($i = $stackPtr; $i > 0; $i--) { if (false === strpos($tokens[$i]['content'], "\n")) { continue; } else { $prevLineToken = $i; break; } } if (is_null($prevLineToken)) { $phpcsFile->addWarning($error, $stackPtr); return null; } $prevNonWhiteSpace = null; for ($i = $prevLineToken; $i > 0; $i--) { if (T_WHITESPACE === $tokens[$i]['code']) { continue; } else { $prevNonWhiteSpace = $i; break; } } if (!is_null($prevNonWhiteSpace)) { $prevLine = $tokens[$prevLineToken]['line']; $prevNonWhiteSpaceLine = $tokens[$prevNonWhiteSpace]['line']; if ($prevLine === $prevNonWhiteSpaceLine) { $phpcsFile->addWarning($error, $stackPtr); } } }
/** * Processes this test when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * @param int $currScope A pointer to the start of the scope. * * @return void */ protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) { $className = $phpcsFile->getDeclarationName($currScope); $methodName = $phpcsFile->getDeclarationName($stackPtr); if (strcasecmp($methodName, $className) === 0) { $error = 'PHP4 style constructors are discouraged; use "__construct()" instead'; $phpcsFile->addWarning($error, $stackPtr, 'OldStyle'); } else { if (strcasecmp($methodName, '__construct') !== 0) { // Not a constructor. return; } } $tokens = $phpcsFile->getTokens(); $parentClassName = $phpcsFile->findExtendedClassName($currScope); if ($parentClassName === false) { return; } $endFunctionIndex = $tokens[$stackPtr]['scope_closer']; $startIndex = $stackPtr; while ($doubleColonIndex = $phpcsFile->findNext(array(T_DOUBLE_COLON), $startIndex, $endFunctionIndex)) { if ($tokens[$doubleColonIndex + 1]['code'] === T_STRING && $tokens[$doubleColonIndex + 1]['content'] === $parentClassName) { $error = 'PHP4 style calls to parent constructors are discouraged; use "parent::__construct()" instead'; $phpcsFile->addWarning($error, $doubleColonIndex + 1, 'OldStyleCall'); } $startIndex = $doubleColonIndex + 1; } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { if ($stackPtr > 0) { return; } $dversion = '7'; $fileName = $phpcsFile->getFileName(); if (!preg_match('/\\.info$/', $fileName)) { return; } $utils = Security_Sniffs_UtilsFactory::getInstance('Drupal7'); $tokens = $phpcsFile->getTokens(); $info = $utils->drupal_parse_info_format(file_get_contents($fileName)); if (isset($info) && count($info) && array_key_exists('project', $info) && array_key_exists($info['project'], $utils::$ContribAdvisories)) { if ($utils::$ContribAdvisories[$info['project']][0][0] == 'abandoned') { $phpcsFile->addError("Module " . $info['project'] . " is abandoned due to a security issue the maintainer never fixed. Details: " . $utils::$ContribAdvisories[$info['project']][0][1], $stackPtr, 'D7ErrAdvisoriesContribAbandonned'); return; } if ($utils::$ContribAdvisories[$info['project']][0][0] == 'unsupported') { $phpcsFile->addError("Module " . $info['project'] . " is unsupported due to unfixed security issue. The Drupal Security Team recommends that this module be uninstalled immediately Details: " . $utils::$ContribAdvisories[$info['project']][0][1], $stackPtr, 'D7ErrAdvisoriesContribUnsupported'); return; } if (array_key_exists('core', $info) && array_key_exists('version', $info)) { if (strpos($info['core'], $dversion) === 0) { foreach ($utils::$ContribAdvisories[$info['project']] as $vcve) { list($a, $CVEversion) = explode('-', $vcve[0]); if ($a != $info['core']) { echo "WARNING Drupal core version inconsistence!!"; } list($a, $mversion) = explode('-', $info['version']); $CVEversion = (double) $CVEversion; if (preg_match('/dev/', $vcve[0])) { $phpcsFile->addWarning("WARNING module " . $info['project'] . " does not have any release for the security fix, manual checking required. Details: " . $vcve[1], $stackPtr, 'D7WarnAdvisoriesContribDev'); } if (preg_match('/rc|alpha|beta/', $vcve[0])) { $phpcsFile->addWarning("WARNING module " . $info['project'] . " is using special version tagging around the security fix, manual checking recommanded. Details: " . $vcve[1], $stackPtr, 'D7WarnAdvisoriesContribrc'); } $mversion = (double) $mversion; $diff = $CVEversion - $mversion; if ($diff > 0 && $diff < 1) { $phpcsFile->addError("Module " . $info['project'] . " " . $info['version'] . " contains security issue and must be updated to at least {$vcve['0']}. Details: " . $vcve[1], $stackPtr, 'D7ErrAdvisoriesContribFoundMinor'); } elseif ($diff >= 1) { $phpcsFile->addWarning("Module " . $info['project'] . " " . $info['version'] . " is out of date a major version and might contains security issue. " . $vcve[1], $stackPtr, 'D7WarnAdvisoriesContribFoundMajor'); } elseif ($diff <= 0) { if (preg_match('/x$/', $vcve[0])) { $phpcsFile->addError("Module " . $info['project'] . " " . $info['version'] . " contains security issue to all {$vcve['0']} versions. " . $vcve[1], $stackPtr, 'D7ErrAdvisoriesContribFoundMajor'); } else { //echo "$fileName: SAFE! " . $info['version'] . "\n"; } } else { echo "MAJOR ERROR IN LOGIC!!!!!\n"; } } } } else { $phpcsFile->addWarning("Module " . $info['project'] . " is listed in advisories but file doesn't provide version information. Please use packages from drupal.org", $stackPtr, 'D7WarnAdvisoriesContribNoInfo'); } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['code'] == T_CONTINUE) { $phpcsFile->addWarning($this->getReqPrefix('WRN.PHP.2.5.4') . 'Использование ' . $tokens[$stackPtr]['content'] . ' не рекомендовано', $stackPtr); } elseif ($tokens[$stackPtr]['code'] == T_BREAK && T_SWITCH != end($tokens[$stackPtr]['conditions'])) { $phpcsFile->addWarning($this->getReqPrefix('WRN.PHP.2.5.4') . 'Использование ' . $tokens[$stackPtr]['content'] . ' не рекомендовано', $stackPtr); } }
/** * Report coding standard violation if class/interface/trait/function is too big * * @param PHPParser_Node $node Current node * * {@internal 'maximum' is padded to compensate for opening/closing curly braces }} */ private function checkSize($node) { $keyword = $this->metaData[$node->getType()]['keyword']; $maximum = $this->metaData[$node->getType()]['maximum']; $size = $node->getAttribute('endLine') - $node->getAttribute('startLine'); if ($size <= $maximum + 2) { return; } $this->phpcsFile->addWarning(sprintf('Keep your %s small (no more than %d lines)', $keyword, $maximum), $this->findStackPointer($node)); }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $find = PHP_CodeSniffer_Tokens::$methodPrefixes; $find[] = T_WHITESPACE; $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true); if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG && $tokens[$commentEnd]['code'] !== T_COMMENT) { return; } if ($tokens[$commentEnd]['code'] === T_COMMENT) { return; } $commentStart = $tokens[$commentEnd]['comment_opener']; $empty = array(T_DOC_COMMENT_WHITESPACE, T_DOC_COMMENT_STAR); $short = $phpcsFile->findNext($empty, $commentStart + 1, $commentEnd, true); if ($short === false) { // No content at all. return; } // Account for the fact that a short description might cover // multiple lines. $shortContent = $tokens[$short]['content']; $shortEnd = $short; for ($i = $short + 1; $i < $commentEnd; $i++) { if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) { if ($tokens[$i]['line'] === $tokens[$shortEnd]['line'] + 1) { $shortContent .= $tokens[$i]['content']; $shortEnd = $i; } else { break; } } } // Check if hook implementation doc is formated correctly. if (preg_match('/^[\\s]*Implement[^\\n]+?hook_[^\\n]+/i', $shortContent, $matches)) { if (!strstr($matches[0], 'Implements ') || strstr($matches[0], 'Implements of') || !preg_match('/ (drush_)?hook_[a-zA-Z0-9_]+\\(\\)( for [a-z0-9_-]+(\\(\\)|\\.tpl\\.php|\\.html.twig))?\\.$/', $matches[0])) { $phpcsFile->addWarning('Format should be "* Implements hook_foo().", "* Implements hook_foo_BAR_ID_bar() for xyz_bar().",, "* Implements hook_foo_BAR_ID_bar() for xyz-bar.html.twig.", or "* Implements hook_foo_BAR_ID_bar() for xyz-bar.tpl.php.".', $short); } else { // Check that a hook implementation does not duplicate @param and // @return documentation. foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) { if ($tokens[$tag]['content'] === '@param') { $warn = 'Hook implementations should not duplicate @param documentation'; $phpcsFile->addWarning($warn, $tag, 'HookParamDoc'); } if ($tokens[$tag]['content'] === '@return') { $warn = 'Hook implementations should not duplicate @return documentation'; $phpcsFile->addWarning($warn, $tag, 'HookReturnDoc'); } } } //end if } //end if }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket) { $tokens = $phpcsFile->getTokens(); $argument = $this->getArgument(1); if ($argument === false) { $error = 'Empty calls to t() are not allowed'; $phpcsFile->addError($error, $stackPtr, 'EmptyT'); return; } if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a translatable string literal. $warning = 'Only string literals should be passed to t() where possible'; $phpcsFile->addWarning($warning, $argument['start'], 'NotLiteralString'); return; } $string = $tokens[$argument['start']]['content']; if ($string === '""' || $string === "''") { $warning = 'Do not pass empty strings to t()'; $phpcsFile->addWarning($warning, $argument['start'], 'EmptyString'); return; } $concatAfter = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $closeBracket + 1, null, true, null, true); if ($concatAfter !== false && $tokens[$concatAfter]['code'] === T_STRING_CONCAT) { $stringAfter = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $concatAfter + 1, null, true, null, true); if ($stringAfter !== false && $tokens[$stringAfter]['code'] === T_CONSTANT_ENCAPSED_STRING && strpos($tokens[$stringAfter]['content'], '<') === false) { $warning = 'Do not concatenate strings to translatable strings, they should be part of the t() argument and you should use placeholders'; $phpcsFile->addWarning($warning, $stringAfter, 'ConcatString'); } } $lastChar = substr($string, -1); if ($lastChar === '"' || $lastChar === "'") { $message = substr($string, 1, -1); if ($message !== trim($message)) { $warning = 'Translatable strings must not begin or end with white spaces, use placeholders with t() for variables'; $phpcsFile->addWarning($warning, $argument['start'], 'WhiteSpace'); } } $concatFound = $phpcsFile->findNext(T_STRING_CONCAT, $argument['start'], $argument['end']); if ($concatFound !== false) { $error = 'Concatenating translatable strings is not allowed, use placeholders instead and only one string literal'; $phpcsFile->addError($error, $concatFound, 'Concat'); } // Check if there is a backslash escaped single quote in the string and // if the string makes use of double quotes. if ($string[0] === "'" && strpos($string, "\\'") !== false && strpos($string, '"') === false) { $warn = 'Avoid backslash escaping in translatable strings when possible, use "" quotes instead'; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashSingleQuote'); return; } if ($string[0] === '"' && strpos($string, '\\"') !== false && strpos($string, "'") === false) { $warn = "Avoid backslash escaping in translatable strings when possible, use '' quotes instead"; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashDoubleQuote'); } }
/** * Processes the tokens that this sniff is interested in. * * @name process * @access public * @see PHP_CodeSniffer_Sniff::process() * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr - 1]['type'] !== 'T_WHITESPACE') { $warning = 'Whitespace is expected before any concat operator "."'; $phpcsFile->addWarning($warning, $stackPtr, 'Found'); } if ($tokens[$stackPtr + 1]['type'] !== 'T_WHITESPACE') { $warning = 'Whitespace is expected after any concat operator "."'; $phpcsFile->addWarning($warning, $stackPtr, 'Found'); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens.. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['code'] === T_FUNCTION) { $methodProps = $phpcsFile->getMethodProperties($stackPtr); // Abstract methods do not require a closing comment. if ($methodProps['is_abstract'] === true) { return; } // If this function is in an interface then we don't require // a closing comment. if ($phpcsFile->hasCondition($stackPtr, T_INTERFACE) === true) { return; } if (isset($tokens[$stackPtr]['scope_closer']) === false) { $error = 'Possible parse error: non-abstract method defined as abstract'; $phpcsFile->addWarning($error, $stackPtr); return; } $decName = $phpcsFile->getDeclarationName($stackPtr); $comment = '//end ' . $decName . '()'; } else { if ($tokens[$stackPtr]['code'] === T_CLASS) { $comment = '//end class'; } else { $comment = '//end interface'; } } //end if if (isset($tokens[$stackPtr]['scope_closer']) === false) { $error = 'Possible parse error: '; $error .= $tokens[$stackPtr]['content']; $error .= ' missing opening or closing brace'; $phpcsFile->addWarning($error, $stackPtr); return; } $closingBracket = $tokens[$stackPtr]['scope_closer']; if ($closingBracket === null) { // Possible inline structure. Other tests will handle it. return; } $error = 'Expected ' . $comment; if (isset($tokens[$closingBracket + 1]) === false || $tokens[$closingBracket + 1]['code'] !== T_COMMENT) { $phpcsFile->addError($error, $closingBracket); return; } if (rtrim($tokens[$closingBracket + 1]['content']) !== $comment) { $phpcsFile->addError($error, $closingBracket); return; } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $token = $tokens[$stackPtr]; // Skip invalid statement. if (isset($token['parenthesis_opener']) === false) { return; } $next = ++$token['parenthesis_opener']; $end = --$token['parenthesis_closer']; $parts = array(0, 0, 0); $index = 0; for (; $next <= $end; ++$next) { $code = $tokens[$next]['code']; if ($code === T_SEMICOLON) { ++$index; } else { if (in_array($code, PHP_CodeSniffer_Tokens::$emptyTokens) === false) { ++$parts[$index]; } } } if ($parts[0] === 0 && $parts[2] === 0 && $parts[1] > 0) { $error = 'This FOR loop can be simplified to a WHILE loop'; $phpcsFile->addWarning($error, $stackPtr, 'CanSimplify'); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being processed. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['scope_opener']) === false) { $error = 'Possible parse error: %s missing opening or closing brace'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data); return; } // Determine the name of the class or interface. Note that we cannot // simply look for the first T_STRING because a class name // starting with the number will be multiple tokens. $opener = $tokens[$stackPtr]['scope_opener']; $nameStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, $opener, true); $nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener); $name = trim($phpcsFile->getTokensAsString($nameStart, $nameEnd - $nameStart)); // Check for camel caps format. $valid = PHP_CodeSniffer::isCamelCaps($name, true, true, false); if ($valid === false) { $type = ucfirst($tokens[$stackPtr]['content']); $error = '%s name "%s" is not in camel caps format'; $data = array($type, $name); $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data); } }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (!array_key_exists('scope_opener', $tokens[$stackPtr])) { return; } for ($ptr = $tokens[$stackPtr]['scope_opener'] + 1; $ptr < $tokens[$stackPtr]['scope_closer']; $ptr++) { $content = $tokens[$ptr]['content']; if ($tokens[$ptr]['code'] !== T_STRING || in_array($ptr, $this->processedStackPointers)) { continue; } $error = ''; $code = ''; if (in_array($content, $this->countFunctions)) { $error = 'Array size calculation function %s detected in loop'; $code = 'ArraySize'; } else { if (in_array($content, $this->modelLsdMethods)) { $error = 'Model LSD method %s detected in loop'; $code = 'ModelLSD'; } else { if (in_array($content, $this->dataLoadMethods)) { $error = 'Data load %s method detected in loop'; $code = 'DataLoad'; } } } if ($error) { $phpcsFile->addWarning($error, $ptr, $code, array($content . '()')); $this->processedStackPointers[] = $ptr; } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $ignore = array(T_DOUBLE_COLON, T_OBJECT_OPERATOR, T_FUNCTION, T_CONST); $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if (in_array($tokens[$prevToken]['code'], $ignore) === true) { // Not a call to a PHP function. return; } $function = strtolower($tokens[$stackPtr]['content']); if ($function != 'ini_get' && $function != 'ini_set') { return; } $iniToken = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr, null); $filteredToken = str_replace(array('"', "'"), array("", ""), $tokens[$iniToken]['content']); if (in_array($filteredToken, array_keys($this->newIniDirectives)) === false) { return; } $error = ''; foreach ($this->newIniDirectives[$filteredToken] as $version => $present) { if (!is_null(PHP_CodeSniffer::getConfigData('testVersion')) && version_compare(PHP_CodeSniffer::getConfigData('testVersion'), $version) <= 0) { if ($present === true) { $error .= " not available before version " . $version; } } } if (strlen($error) > 0) { $error = "INI directive '" . $filteredToken . "' is" . $error; $phpcsFile->addWarning($error, $stackPtr); } }
/** * Processes the function tokens within the class. * * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. * @param int $stackPtr The position where the token was found. * * @return void */ protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'][1] === '_') { $error = 'Property name "%s" should not be prefixed with an underscore to indicate visibility'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data); } // Detect multiple properties defined at the same time. Throw an error // for this, but also only process the first property in the list so we don't // repeat errors. $find = PHP_CodeSniffer_Tokens::$scopeModifiers; $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON)); $prev = $phpcsFile->findPrevious($find, $stackPtr - 1); if ($tokens[$prev]['code'] === T_VARIABLE) { return; } if ($tokens[$prev]['code'] === T_VAR) { $error = 'The var keyword must not be used to declare a property'; $phpcsFile->addError($error, $stackPtr, 'VarUsed'); } $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), $stackPtr + 1); if ($tokens[$next]['code'] === T_VARIABLE) { $error = 'There must not be more than one property declared per statement'; $phpcsFile->addError($error, $stackPtr, 'Multiple'); } $modifier = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, $stackPtr); if ($modifier === false || $tokens[$modifier]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Visibility must be declared on property "%s"'; $data = array($tokens[$stackPtr]['content']); $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $ignore = array(T_DOUBLE_COLON, T_OBJECT_OPERATOR, T_FUNCTION, T_CONST); $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if (in_array($tokens[$prevToken]['code'], $ignore) === true) { // Not a call to a PHP function. return; } $function = strtolower($tokens[$stackPtr]['content']); if ($function != 'ini_get' && $function != 'ini_set') { return; } $iniToken = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr, null); $iniDirective = str_replace("'", "", $tokens[$iniToken]['content']); if (in_array($iniDirective, $this->deprecatedIniDirectives) === true) { $error = "[PHP 5.4] INI directive " . $tokens[$iniToken]['content'] . " is deprecated."; $phpcsFile->addWarning($error, $stackPtr); } else { if (in_array($iniDirective, $this->removedIniDirectives) === true) { $error = "[PHP 5.4] INI directive " . $tokens[$iniToken]['content'] . " is removed."; $phpcsFile->addError($error, $stackPtr); } } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param integer $stackPtr The position of the current token in * the token stack. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['scope_closer']) === false) { return; } $className = $phpcsFile->getDeclarationName($stackPtr); $errorData = array(strtolower($tokens[$stackPtr]['content'])); $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), $tokens[$stackPtr]['scope_closer'] + 1); if ($nextClass !== false) { $nextClassName = $phpcsFile->getDeclarationName($nextClass); $extends = $phpcsFile->findExtendedClassName($nextClass); if ($className == $nextClassName && $extends != $className && substr($extends, -1 * (strlen($className) + 1)) == '\\' . $className) { // $nextClassName wraps $className in global namespace (probably) $phpcsFile->recordMetric($stackPtr, 'One class per file', 'yes'); } else { $error = 'Each %s must be in a file by itself'; $phpcsFile->addError($error, $nextClass, 'MultipleClasses', $errorData); $phpcsFile->recordMetric($stackPtr, 'One class per file', 'no'); } } else { $phpcsFile->recordMetric($stackPtr, 'One class per file', 'yes'); } if (version_compare(PHP_VERSION, '5.3.0') >= 0) { $namespace = $phpcsFile->findNext(array(T_NAMESPACE, T_CLASS, T_INTERFACE, T_TRAIT), 0); if ($tokens[$namespace]['code'] !== T_NAMESPACE) { $error = 'Each %s must be in a namespace of at least one level (a top-level vendor name)'; $phpcsFile->addWarning($error, $stackPtr, 'MissingNamespace', $errorData); $phpcsFile->recordMetric($stackPtr, 'Class defined in namespace', 'no'); } else { $phpcsFile->recordMetric($stackPtr, 'Class defined in namespace', 'yes'); } } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $content = $tokens[$stackPtr]["content"]; $recommendations = array("!=" => "!==", "==" => "==="); $phpcsFile->addWarning($this->getReqPrefix("WRN.JS.3.13.3") . "Use '" . $recommendations[$content] . "' instead of '{$content}'", $stackPtr); }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Check for global input variable if (!in_array($tokens[$stackPtr]['content'], array('$_GET', '$_POST', '$_REQUEST'))) { return; } $varName = $tokens[$stackPtr]['content']; // If we're overriding a superglobal with an assignment, no need to test $semicolon_position = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr + 1, null, null, null, true); $assignment_position = $phpcsFile->findNext(array(T_EQUAL), $stackPtr + 1, null, null, null, true); if ($semicolon_position !== false && $assignment_position !== false && $assignment_position < $semicolon_position) { return; } // Check for whitelisting comment $currentLine = $tokens[$stackPtr]['line']; $nextPtr = $stackPtr; while (isset($tokens[$nextPtr + 1]['line']) && $tokens[$nextPtr + 1]['line'] == $currentLine) { $nextPtr++; // Do nothing, we just want the last token of the line } $is_whitelisted = $tokens[$nextPtr]['code'] === T_COMMENT && preg_match('#input var okay#i', $tokens[$nextPtr]['content']) > 0; if (!$is_whitelisted) { $phpcsFile->addWarning('Detected access of super global var %s, probably need manual inspection.', $stackPtr, null, array($varName)); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $namespace = ''; $stackPtr = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_NAMESPACE), 0); while ($stackPtr !== false) { // Keep track of what namespace we are in. if ($tokens[$stackPtr]['code'] === T_NAMESPACE) { $nsEnd = $phpcsFile->findNext(array(T_NS_SEPARATOR, T_STRING, T_WHITESPACE), $stackPtr + 1, null, true); $namespace = trim($phpcsFile->getTokensAsString($stackPtr + 1, $nsEnd - $stackPtr - 1)); $stackPtr = $nsEnd; } else { $nameToken = $phpcsFile->findNext(T_STRING, $stackPtr); $name = $tokens[$nameToken]['content']; if ($namespace !== '') { $name = $namespace . '\\' . $name; } $compareName = strtolower($name); if (isset($this->foundClasses[$compareName]) === true) { $type = strtolower($tokens[$stackPtr]['content']); $file = $this->foundClasses[$compareName]['file']; $line = $this->foundClasses[$compareName]['line']; $error = 'Duplicate %s name "%s" found; first defined in %s on line %s'; $data = array($type, $name, $file, $line); $phpcsFile->addWarning($error, $stackPtr, 'Found', $data); } else { $this->foundClasses[$compareName] = array('file' => $phpcsFile->getFilename(), 'line' => $tokens[$stackPtr]['line']); } } $stackPtr = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_NAMESPACE), $stackPtr + 1); } //end while }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $workingString = $tokens[$stackPtr]['content']; // Check if it's a double quoted string. if (strpos($workingString, '"') === false) { return; } // Make sure it's not a part of a string started above. // If it is, then we have already checked it. if ($workingString[0] !== '"') { return; } // Work through the following tokens, in case this string is stretched // over multiple Lines. for ($i = $stackPtr + 1; $i < $phpcsFile->numTokens; $i++) { if ($tokens[$i]['type'] !== 'T_CONSTANT_ENCAPSED_STRING') { break; } $workingString .= $tokens[$i]['content']; } $allowedChars = array('\\n', '\\r', '\\f', '\\t', '\\v', '\\x', '\''); foreach ($allowedChars as $testChar) { if (strpos($workingString, $testChar) !== false) { return; } } $error = "[Expresiones#strings] String does not require double quotes; use single quotes instead"; $phpcsFile->addWarning($error, $stackPtr); }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { if ($phpcsFile->getTokensAsString($stackPtr, 4) === '$form_state[\'input\']' || $phpcsFile->getTokensAsString($stackPtr, 4) === '$form_state["input"]') { $warning = 'Do not use the raw $form_state[\'input\'], use $form_state[\'values\'] instead where possible'; $phpcsFile->addWarning($warning, $stackPtr, 'Input'); } }
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $ignore = array(T_DOUBLE_COLON, T_OBJECT_OPERATOR, T_FUNCTION, T_CONST); $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if (in_array($tokens[$prevToken]['code'], $ignore) === true) { // Not a call to a PHP function. return; } $function = strtolower($tokens[$stackPtr]['content']); if ($function != 'ini_get' && $function != 'ini_set') { return; } $iniToken = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr, null); if (in_array(str_replace("'", "", $tokens[$iniToken]['content']), array_keys($this->deprecatedIniDirectives)) === false) { return; } $error = ''; foreach ($this->deprecatedIniDirectives[str_replace("'", "", $tokens[$iniToken]['content'])] as $version => $forbidden) { if (is_null(PHP_CodeSniffer::getConfigData('testVersion')) || !is_null(PHP_CodeSniffer::getConfigData('testVersion')) && version_compare(PHP_CodeSniffer::getConfigData('testVersion'), $version) >= 0) { if ($forbidden === true) { $error .= " forbidden"; } else { $error .= " deprecated"; } $error .= " in PHP " . $version . " and"; } } if (strlen($error) > 0) { $error = "INI directive " . $tokens[$iniToken]['content'] . " is" . $error; $error = substr($error, 0, strlen($error) - 4) . "."; $phpcsFile->addWarning($error, $stackPtr); } }
/** * Processes the tokens that this sniff is interested in. * * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. * @param int $stackPtr The position in the stack where * the token was found. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $utils = new Security_Sniffs_Drupal7_Utils(); $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] == 'drupal_http_request') { $closer = $phpcsFile->findNext(T_SEMICOLON, $stackPtr); $s = $closer; $warn = 1; while ($s) { $s = $phpcsFile->findPrevious(array(T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_QUOTED_STRING), $s - 1); if ($tokens[$s]['content'] == "'verify_peer'" || $tokens[$s]['content'] == '"verify_peer"') { $warn = 0; } } if ($warn) { $phpcsFile->addWarning('Verify that drupal_http_request uses HTTPS and is called with verify_peer in order to validate the certificate', $stackPtr, 'D7HttpRequestSSL'); } $d = $utils::findDirtyParam($phpcsFile, $stackPtr); if ($d && $utils::is_token_user_input($tokens[$d])) { $phpcsFile->addError('drupal_http_request called with direct user input ' . $tokens[$d]['content'], $stackPtr, 'D7HttpRequestUserInputErr'); } elseif ($d && PHP_CodeSniffer::getConfigData('ParanoiaMode')) { $phpcsFile->addWarning('drupal_http_request called with variable ' . $tokens[$d]['content'], $stackPtr, 'D7HttpRequestUserInputErr'); } } }