/** * 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(); // Make sure this is the first PHP open tag so we don't process // the same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $fileName = $phpcsFile->getFileName(); $extension = substr($fileName, strrpos($fileName, '.')); $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), $stackPtr); if ($extension === '.php') { if ($nextClass !== false) { $error = '%s found in ".php" file; use ".inc" extension instead'; $data = array(ucfirst($tokens[$nextClass]['content'])); $phpcsFile->addError($error, $stackPtr, 'ClassFound', $data); } } else { if ($extension === '.inc') { if ($nextClass === false) { $error = 'No interface or class found in ".inc" file; use ".php" extension instead'; $phpcsFile->addError($error, $stackPtr, 'NoClass'); } } } }
/** * 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(); // Make sure this is the first PHP open tag so we don't process the // same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $path = $phpcsFile->getFileName(); $properties = $this->properties($path); foreach ($properties + $this->properties as $key => $value) { if (isset($properties[$key]) === true && isset($this->properties[$key]) === false) { $error = 'Unexpected Subversion property "' . $key . '" = "' . $properties[$key] . '"'; $phpcsFile->addError($error, $stackPtr); continue; } if (isset($properties[$key]) === false && isset($this->properties[$key]) === true) { $error = 'Missing Subversion property "' . $key . '" = "' . $this->properties[$key] . '"'; $phpcsFile->addError($error, $stackPtr); continue; } if ($properties[$key] !== $this->properties[$key]) { $error = 'Subversion property "' . $key . '" = "' . $properties[$key] . '" does not match "' . $this->properties[$key] . '"'; $phpcsFile->addError($error, $stackPtr); } } //end foreach }
/** * 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) { $path = $phpcsFile->getFileName(); if (!preg_match("/(views)/i", $path)) { return; } $tokens = $phpcsFile->getTokens(); $classname = $tokens[$phpcsFile->findNext(T_STRING, $stackPtr)]['content']; if (preg_match("/(helpers)/i", $path)) { $final_classname = $this->classname_without_type($classname, "Helper"); $msg_on_error = "Cake convention expects the helper class name to end with 'Helper'"; } else { $final_classname = $this->classname_with_type($classname, "View"); $msg_on_error = "Cake convention expects the view class name to end with 'View'"; } if (is_null($final_classname)) { $phpcsFile->addError($msg_on_error, $stackPtr); return; } $expected_file_name = preg_replace('/([A-Z])/', '_${1}', $final_classname); if (strpos($expected_file_name, "_") === 0) { $expected_file_name = substr($expected_file_name, 1, strlen($expected_file_name)); } $expected_file_name = strtolower($expected_file_name) . ".php"; if (!preg_match("/" . $expected_file_name . "/", $path)) { $error = "File name is expected to be, '" . $expected_file_name . "' for Class with name, '" . $classname . "'"; $phpcsFile->addError($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) { if ($stackPtr > 0) { return; } $fileName = $phpcsFile->getFileName(); if (!preg_match('/includes\\/bootstrap\\.inc$/', $fileName)) { return; } $utils = Security_Sniffs_UtilsFactory::getInstance('Drupal7'); $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] == "'VERSION'") { $s = $phpcsFile->findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr + 1); if (preg_match('/(\\d+)\\.(\\d+)/', $tokens[$s]['content'], $m)) { // Check if it's the right Drupal version if ($m[1] != 7) { return; } $minorversion = $m[2]; } else { // This is not the right Drupal file? return; } foreach ($utils::$CoreAdvisories as $key => $value) { if ($minorversion < $key) { // TODO clean the error and maybe the variable in Utils.. make a loop for fetch all bugs and addErrors? $phpcsFile->addError("FOUND core out of date {$minorversion} {$key}, " . $value[0][0] . " cves: " . $value[0][1], $stackPtr, 'D7AdvCore'); } } } }
/** * 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(); // Make sure this is the first PHP open tag so we don't process the same file twice. if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) { return; } if (($substring = strpbrk(basename($phpcsFile->getFileName()), "_- ")) !== false) { $phpcsFile->addError('Invalid character "%s" found in filename.', $stackPtr, 'InvalidFilenameCharacter', array($substring[0])); } }
/** * Process a pattern. * * Returns if we are inside a "tmpl" folder - workaround for the Joomla! CMS :( * * @param array $patternInfo Information about the pattern used for checking, which includes are * parsed token representation of the pattern. * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the token occured. * @param integer $stackPtr The postion in the tokens stack where the listening token type was found. * * @return return_type */ protected function processPattern($patternInfo, PHP_CodeSniffer_File $phpcsFile, $stackPtr) { if (0) { /* * @todo disabled - This is a special sniff for the Joomla! CMS to exclude * the tmpl folder which may contain constructs in colon notation */ $parts = explode(DIRECTORY_SEPARATOR, $phpcsFile->getFileName()); if ('tmpl' == $parts[count($parts) - 2]) { return false; } } return parent::processPattern($patternInfo, $phpcsFile, $stackPtr); }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $tokenInfo = $tokens[$stackPtr]; $matches = array(); // Look for exact matches of our word preg_match_all("/\\b{$this->oldString}\\b/", $tokenInfo['content'], $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); foreach ($matches[0] as $match) { $offset = $match[1]; $oldStringMatch = $match[0]; $newString = preg_replace("/{$this->oldString}/", $this->newString, $oldStringMatch); $this->_changeRegistry->addChange($phpcsFile->getFileName(), $tokenInfo['line'], $tokenInfo['column'] + $offset, strlen($oldStringMatch), $newString, $this->tentative); } }
/** * Processes this sniff, 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) { // Make sure this is the first PHP open tag so we don't process // the same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $fileName = $phpcsFile->getFileName(); $extension = substr($fileName, strrpos($fileName, '.')); if ($extension !== '.php') { $error = 'Extension for PHP files is always ".php". Found "' . $extension . '" file; use ".php" extension instead'; $phpcsFile->addError($error, $stackPtr, 'WrongFileExtension'); } }
/** * 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(); // Make sure this is the first PHP open tag so we don't process // the same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $fileName = basename($phpcsFile->getFileName()); if (strpos($fileName, '_') !== false) { $expected = str_replace('_', '-', $fileName); $error = ucfirst('Filename "' . $fileName . '" with underscores found; use ' . $expected . ' instead'); $phpcsFile->addError($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) { $tokens = $phpcsFile->getTokens(); // Make sure this is the first PHP open tag so we don't process // the same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $fileName = $phpcsFile->getFileName(); $extension = substr($fileName, strrpos($fileName, '.')); $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), $stackPtr); if ($extension === '.inc') { $error = 'Do not use .inc for classes or inclusions, that is so PHP4'; $phpcsFile->addError($error, $stackPtr, 'NoClass'); } }
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $fileName = $phpcsFile->getFileName(); $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), $stackPtr); if (false !== strpos($fileName, '.class.php')) { if ($nextClass === false) { $error = 'No interface or class found in ".class.php" file; use ".php" extension instead'; $phpcsFile->addError($error, $stackPtr); } } elseif (false !== strpos($fileName, '.php')) { if ($nextClass !== false && false === strpos($fileName, 'model')) { $error = 'Use ".class.php" extension for the class file'; $phpcsFile->addError($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 int */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $fileName = $phpcsFile->getFileName(); $extension = substr($fileName, strrpos($fileName, '.')); $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), $stackPtr); if ($nextClass !== false) { $phpcsFile->recordMetric($stackPtr, 'File extension for class files', $extension); if ($extension === '.php') { $error = '%s found in ".php" file; use ".inc" extension instead'; $data = array(ucfirst($tokens[$nextClass]['content'])); $phpcsFile->addError($error, $stackPtr, 'ClassFound', $data); } } else { $phpcsFile->recordMetric($stackPtr, 'File extension for non-class files', $extension); if ($extension === '.inc') { $error = 'No interface or class found in ".inc" file; use ".php" extension instead'; $phpcsFile->addError($error, $stackPtr, 'NoClass'); } } // Ignore the rest of the file. return $phpcsFile->numTokens + 1; }
/** * 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(); // Make sure this is the first PHP open tag so we don't process the // same file twice. $prevOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1); if ($prevOpenTag !== false) { return; } $path = $phpcsFile->getFileName(); $properties = $this->getProperties($path); if ($properties === null) { // Not under version control. return; } $allProperties = $properties + $this->properties; foreach ($allProperties as $key => $value) { if (isset($properties[$key]) === true && isset($this->properties[$key]) === false) { $error = 'Unexpected Subversion property "%s" = "%s"'; $data = array($key, $properties[$key]); $phpcsFile->addError($error, $stackPtr, 'Unexpected', $data); continue; } if (isset($properties[$key]) === false && isset($this->properties[$key]) === true) { $error = 'Missing Subversion property "%s" = "%s"'; $data = array($key, $this->properties[$key]); $phpcsFile->addError($error, $stackPtr, 'Missing', $data); continue; } if ($properties[$key] !== null && $properties[$key] !== $this->properties[$key]) { $error = 'Subversion property "%s" = "%s" does not match "%s"'; $data = array($key, $properties[$key], $this->properties[$key]); $phpcsFile->addError($error, $stackPtr, 'NoMatch', $data); } } //end foreach }
/** * Processes this sniff, 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(); $findTokens = array(T_CLASS, T_INTERFACE); $stackPtr = $phpcsFile->findNext($findTokens, $stackPtr + 1); // Check if we hit a file without a class. Raise a warning and return. if ($stackPtr === false) { $warning = 'Its recommended to use only PHP classes and avoid non-class files.'; $phpcsFile->addWarning($warning, 1, 'Non-ClassFileFound'); return; } $classNameToken = $phpcsFile->findNext(T_STRING, $stackPtr); $className = $tokens[$classNameToken]['content']; $fullPath = basename($phpcsFile->getFileName()); $fileName = substr($fullPath, 0, strrpos($fullPath, '.')); if ($fileName === '') { // No filename probably means STDIN, so we can't do this check. return; } if (strcmp($fileName, $className) !== 0) { $error = 'The classname is not equal to the filename; found "%s" as classname and "%s" for filename.'; $data = array($className, $fileName . '.php'); $phpcsFile->addError($error, $stackPtr, 'ClassnameNotEqualToFilename', $data); } if (strtolower($fileName) === $fileName) { $error = 'The filename has to be in UpperCamelCase; found "%s".'; $data = array($fileName . '.php'); $phpcsFile->addError($error, $stackPtr, 'LowercaseFilename', $data); } if ($tokens[$stackPtr]['code'] === T_INTERFACE) { if (stristr($fileName, 'Interface') === false) { $error = 'The file contains an interface but the string "Interface" is not part of the filename; found "%s", but expected "%s".'; $data = array($fileName . '.php', $className . '.php'); $phpcsFile->addError($error, $stackPtr, 'InterfaceNotInFilename', $data); } } }
/** * Figure out the relevant scope opener * @param PHP_CodeSniffer_File $phpcsFile The file the variable is in * @param int $varPtr The position in the stack in which our variable has scope * @param string $varName the name of the variable. * @return int the stack pointer that opens the scope for this variable */ private function getScopeOwner($varPtr, $phpcsFile, $varName) { $tokens = $phpcsFile->getTokens(); $varInfo = $tokens[$varPtr]; $scopes = self::filterScopes($varInfo['conditions']); if ($varName[0] != '$' && $varName[0] != '*') { // If we're dealing with a fully qualified variable, put it in the global scope $scopeOpen = SCISR_SCOPE_CLASS; } else { if ($this->isGlobal($varPtr, $phpcsFile->getFileName(), $scopes, $varName)) { // If the variable was declared global, use that $scopeOpen = SCISR_SCOPE_GLOBAL; } else { // Get the lowermost scope $scopeOpen = $scopes[count($scopes) - 1]; } } return $scopeOpen; }