Standards are specified by classes that implement the PHP_CodeSniffer_Sniff interface. A sniff registers what token types it wishes to listen for, then PHP_CodeSniffer encounters that token, the sniff is invoked and passed information about where the token was found in the stack, and the token stack itself. Sniff files and their containing class must be prefixed with Sniff, and have an extension of .php. Multiple PHP_CodeSniffer operations can be performed by re-calling the process function with different parameters.
Author: Greg Sherwood (gsherwood@squiz.net)
Author: Marc McIntyre (mmcintyre@squiz.net)
 /**
  * Called when one of the token types that this sniff is listening for
  * is found.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
  *                                        token was found.
  * @param int                  $stackPtr  The position in the PHP_CodeSniffer
  *                                        file's token stack where the token
  *                                        was found.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->_phpCsFile = $phpcsFile;
     $varRegExp = '/\\$[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/';
     $tokens = $phpcsFile->getTokens();
     $content = $tokens[$stackPtr]['content'];
     $matches = array();
     if (preg_match_all($varRegExp, $content, $matches, PREG_OFFSET_CAPTURE) === 0) {
         return;
     }
     foreach ($matches as $match) {
         foreach ($match as $info) {
             list($var, $pos) = $info;
             if ($pos === 1 || $content[$pos - 1] !== '{') {
                 if (strpos(substr($content, 0, $pos), '{') > 0 && strpos(substr($content, 0, $pos), '}') === false) {
                     continue;
                 }
                 $this->_searchForBackslashes($content, $pos);
                 $fix = $this->_phpCsFile->addFixableError(sprintf('must surround variable %s with { }', $var), $stackPtr, 'NotSurroundedWithBraces');
                 if ($fix === true) {
                     $correctVariable = $this->_surroundVariableWithBraces($content, $pos, $var);
                     $this->_fixPhpCsFile($stackPtr, $correctVariable);
                 }
             }
             //end if
         }
         //end foreach
     }
     //end foreach
 }
Esempio n. 2
0
 public function execute()
 {
     require_once $this->mooshDir . "/includes/codesniffer_cli.php";
     require_once $this->mooshDir . "/includes/coderepair/CodeRepair.php";
     $moodle_sniffs = $this->mooshDir . "/vendor/moodlerooms/moodle-coding-standard/moodle";
     $options = $this->expandedOptions;
     $interactive = $options['interactive'];
     if (isset($options['path'])) {
         $this->checkDirArg($options['path']);
         $path = $options['path'];
     } else {
         $path = $this->cwd;
     }
     $files = $this->_get_files($path);
     if ($options['repair'] === true) {
         $code_repair = new \CodeRepair($files);
         $code_repair->drymode = false;
         $code_repair->start();
     }
     $phpcscli = new \codesniffer_cli();
     $phpcs = new \PHP_CodeSniffer(1, 0, 'utf-8', (bool) $interactive);
     $phpcs->setCli($phpcscli);
     $phpcs->process($files, $moodle_sniffs);
     $phpcs->reporting->printReport('full', false, $phpcscli->getCommandLineValues(), null);
 }
 /**
  * Tests the extending classes Sniff class.
  */
 public final function testSniff()
 {
     // Skip this test if we can't run in this environment.
     if ($this->shouldSkipTest() === true) {
         $this->markTestSkipped();
     }
     $testFiles = $this->getTestFiles();
     $sniffCodes = $this->getSniffCodes();
     self::$phpcs->initStandard(dirname(__DIR__) . '/src/Drupal', $sniffCodes);
     $failureMessages = array();
     foreach ($testFiles as $testFile) {
         try {
             $phpcsFile = self::$phpcs->processFile($testFile);
         } catch (Exception $e) {
             $this->fail('An unexpected exception has been caught: ' . $e->getMessage());
         }
         $failures = $this->generateFailureMessages($phpcsFile);
         $failureMessages = array_merge($failureMessages, $failures);
         if ($phpcsFile->getFixableCount() > 0) {
             // Attempt to fix the errors.
             $phpcsFile->fixer->fixFile();
             $fixable = $phpcsFile->getFixableCount();
             if ($fixable > 0) {
                 $filename = basename($testFile);
                 $failureMessages[] = "Failed to fix {$fixable} fixable violations in {$filename}";
             }
         }
     }
     //end foreach()
     if (empty($failureMessages) === false) {
         $this->fail(implode(PHP_EOL, $failureMessages));
     }
 }
Esempio n. 4
0
 public function execute()
 {
     require_once $this->mooshDir . "/includes/codesniffer/CodeSniffer.php";
     require_once $this->mooshDir . "/includes/codesniffer/lib.php";
     require_once $this->mooshDir . "/includes/coderepair/CodeRepair.php";
     $moodle_sniffs = $this->mooshDir . "/includes/codesniffer/moodle";
     $options = $this->expandedOptions;
     $interactive = $options['interactive'];
     if (isset($options['path'])) {
         $this->checkFileArg($options['path']);
         $path = $options['path'];
     } else {
         $path = $this->cwd;
     }
     $files = $this->_get_files($path);
     if ($options['repair'] === true) {
         $code_repair = new \CodeRepair($files);
         $code_repair->drymode = false;
         $code_repair->start();
     }
     $phpcs = new \PHP_CodeSniffer(1, 0, 'utf-8', false);
     $phpcs->setCli(new \codesniffer_cli());
     $numerrors = $phpcs->process($files, $moodle_sniffs);
     $phpcs->reporting->printReport('full', false, null);
 }
Esempio n. 5
0
 /**
  * Validate the current check
  *
  * Validate the check on the specified repository. Returns an array of 
  * found issues.
  * 
  * @param pchRepository $repository 
  * @return void
  */
 public function validate(pchRepository $repository)
 {
     $cs = new PHP_CodeSniffer();
     $cs->process(array(), $this->standard);
     foreach ($this->getChangedFiles($repository) as $file) {
         $cs->processFile($file, stream_get_contents($this->getFileContents($repository, $file)));
     }
     $issues = array();
     foreach ($cs->getFilesErrors() as $file => $messages) {
         foreach ($messages['errors'] as $errors) {
             foreach ($errors as $line => $lineErrors) {
                 foreach ($lineErrors as $error) {
                     $issues[] = new pchIssue(E_ERROR, $file, $line, $error['source'] . ': ' . $error['message']);
                 }
             }
         }
         foreach ($messages['warnings'] as $errors) {
             foreach ($errors as $line => $lineErrors) {
                 foreach ($lineErrors as $error) {
                     $issues[] = new pchIssue(E_WARNING, $file, $line, $error['source'] . ': ' . $error['message']);
                 }
             }
         }
     }
     return $issues;
 }
 protected static function analyze(array $sniffs, $files)
 {
     $sniffs = array_map(static function ($sniff) {
         $sniff = __DIR__ . '/../../../../src/' . $sniff . '.php';
         static::assertFileExists($sniff, 'Sniff does not exist');
         return $sniff;
     }, $sniffs);
     $files = array_map(static function ($file) {
         static::assertFileExists($file, 'Source file does not exists');
         return $file;
     }, (array) $files);
     $codeSniffer = new PHP_CodeSniffer();
     $codeSniffer->registerSniffs($sniffs, []);
     $codeSniffer->populateTokenListeners();
     $report = [];
     foreach ($files as $file) {
         $phpcsFile = $codeSniffer->processFile($file);
         $report[$file] = [];
         $report[$file]['numWarnings'] = $phpcsFile->getWarningCount();
         $report[$file]['warnings'] = $phpcsFile->getWarnings();
         $report[$file]['numErrors'] = $phpcsFile->getErrorCount();
         $report[$file]['errors'] = $phpcsFile->getErrors();
     }
     return $report;
 }
 /**
  * @test
  * @dataProvider fixturesProvider
  */
 public function it_generates_the_expected_warnings_and_errors($file, array $expectedErrors, array $expectedWarnings)
 {
     $codeSniffer = new \PHP_CodeSniffer();
     $codeSniffer->process(array(), $this->getRulesetXmlPath(), array($this->getRuleName()));
     $sniffedFile = $codeSniffer->processFile($file);
     $this->fileHasExpectedErrors($sniffedFile, $expectedErrors);
     $this->fileHasExpectedWarnings($sniffedFile, $expectedWarnings);
 }
 /**
  * @param $file string
  *
  * @return int ErrorCount
  */
 protected function sniffFile($file)
 {
     $phpCs = new \PHP_CodeSniffer();
     $phpCs->initStandard(realpath(__DIR__ . '/../Standards/Symfony2'));
     $result = $phpCs->processFile($file);
     $errors = $result->getErrorCount();
     return $errors;
 }
Esempio n. 9
0
 protected function executeOnPHPFile(File $file)
 {
     $code_sniffer = new \PHP_CodeSniffer($this->phpcs_verbosity, $this->phpcs_tab_width, $this->phpcs_encoding, self::PHPCS_NOT_INTERACTIVE_MODE);
     //Load the standard
     $code_sniffer->process(array(), $this->standard, array());
     $file_result = $code_sniffer->processFile($file->getPath(), $file->getContent());
     if ($file_result->getErrorCount()) {
         $this->handlePHPCSErrors($file, $file_result);
     }
 }
 /**
  * Create PHP_CodeSniffer instance
  *
  * @param array $restrictions Restrictions
  *
  * @return \PHP_CodeSniffer
  */
 protected function getCodeSniffer(array $restrictions)
 {
     $codeSniffer = new \PHP_CodeSniffer();
     $codeSniffer->cli->setCommandLineValues(array("--report=summary"));
     $infoReporting = $codeSniffer->reporting->factory("summary");
     /** @var \PHP_CodeSniffer_Reports_Info $infoReporting */
     $infoReporting->recordErrors = true;
     $codeSniffer->process(array(), __DIR__ . "/..", $restrictions);
     $codeSniffer->setIgnorePatterns(array());
     return $codeSniffer;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->outputHeading($output, 'Moodle Code Checker on %s');
     $files = $this->plugin->getFiles($this->finder);
     if (count($files) === 0) {
         return $this->outputSkip($output);
     }
     $sniffer = new \PHP_CodeSniffer();
     $sniffer->setCli(new CodeSnifferCLI(['reports' => ['full' => null], 'colors' => true, 'encoding' => 'utf-8', 'showProgress' => true, 'reportWidth' => 120]));
     $sniffer->process($files, $this->standard);
     $results = $sniffer->reporting->printReport('full', false, $sniffer->cli->getCommandLineValues(), null, 120);
     return $results['errors'] > 0 ? 1 : 0;
 }
Esempio n. 12
0
 /**
  * Show the available coding standards
  *
  * @param array $options
  */
 public function showCodestyleStandards($options = [])
 {
     $phpcs = new \PHP_CodeSniffer();
     $standards = $phpcs->getInstalledStandards();
     sort($standards);
     if (!$options['no-ansi']) {
         array_walk($standards, function (&$value) {
             $value = "<fg=green>{$value}</fg=green>";
         });
     }
     $last = array_pop($standards);
     $this->say("Installed coding standards are " . implode(', ', $standards) . " and " . $last);
 }
 /**
  * Tests the extending classes Sniff class.
  *
  * @return void
  * @throws PHPUnit_Framework_Error
  */
 public final function testSniff()
 {
     // Skip this test if we can't run in this environment.
     if ($this->shouldSkipTest() === true) {
         $this->markTestSkipped();
     }
     $testFiles = $this->getTestFiles();
     $sniffCodes = $this->getSniffCodes();
     // Determine the standard to be used from the class name.
     $class_name_parts = explode('_', get_class($this));
     $standard = $class_name_parts[0];
     $failureMessages = array();
     foreach ($testFiles as $testFile) {
         self::$phpcs->initStandard("coder_sniffer/{$standard}", $sniffCodes);
         $filename = basename($testFile);
         try {
             $cliValues = $this->getCliValues($filename);
             self::$phpcs->cli->setCommandLineValues($cliValues);
             $phpcsFile = self::$phpcs->processFile($testFile);
         } catch (Exception $e) {
             $this->fail('An unexpected exception has been caught: ' . $e->getMessage());
         }
         $failures = $this->generateFailureMessages($phpcsFile);
         $failureMessages = array_merge($failureMessages, $failures);
         // Attempt to fix the errors.
         // Re-initialize the standard to use all sniffs for the fixer.
         self::$phpcs->initStandard("coder_sniffer/{$standard}");
         self::$phpcs->cli->setCommandLineValues($cliValues);
         $phpcsFile = self::$phpcs->processFile($testFile);
         $phpcsFile->fixer->fixFile();
         $fixable = $phpcsFile->getFixableCount();
         if ($fixable > 0) {
             $failureMessages[] = "Failed to fix {$fixable} fixable violations in {$filename}";
         }
         // Check for a .fixed file to check for accuracy of fixes.
         $fixedFile = $testFile . '.fixed';
         if (file_exists($fixedFile) === true) {
             $diff = $phpcsFile->fixer->generateDiff($fixedFile);
             if (trim($diff) !== '') {
                 $filename = basename($testFile);
                 $fixedFilename = basename($fixedFile);
                 $failureMessages[] = "Fixed version of {$filename} does not match expected version in {$fixedFilename}; the diff is\n{$diff}";
             }
         }
     }
     //end foreach
     if (empty($failureMessages) === false) {
         $this->fail(implode(PHP_EOL, $failureMessages));
     }
 }
 /**
  * Sniff a file and return resulting file object
  *
  * @param string $filename Filename to sniff
  * @param string $targetPhpVersion Value of 'testVersion' to set on PHPCS object
  * @return PHP_CodeSniffer_File File object
  */
 public function sniffFile($filename, $targetPhpVersion = null)
 {
     if (null !== $targetPhpVersion) {
         PHP_CodeSniffer::setConfigData('testVersion', $targetPhpVersion, true);
     }
     $filename = realpath(dirname(__FILE__)) . DIRECTORY_SEPARATOR . $filename;
     try {
         $phpcsFile = self::$phpcs->processFile($filename);
     } catch (Exception $e) {
         $this->fail('An unexpected exception has been caught: ' . $e->getMessage());
         return false;
     }
     return $phpcsFile;
 }
 /**
  * Runs PHP sniff analysis.
  *
  * @return []string
  * Textual summary of the analysis.
  */
 function getSniffAnalysis(Module $module, $extensions)
 {
     #print_r(get_defined_vars());
     $verbosity = 1;
     // Run php analyser directly as PHP.
     $phpcs = new \PHP_CodeSniffer($verbosity);
     // Need to emulate a CLI environment in order to pass certain settings down
     // to the internals.
     // Decoupling here is atrocious.
     $cli = new SniffReporter();
     $phpcs->setCli($cli);
     // Parameters passed to phpcs.
     // Normally we just name the standard,
     // but passing the full path to it also works.
     $values = array('standard' => 'Drupal', 'sniffs' => array());
     try {
         $phpcs->initStandard($values['standard'], $values['sniffs']);
     } catch (Exception $e) {
         $message = "Could not initialize coding standard " . $values['standard'] . " " . $e->getMessage();
         error_log($message);
         return array($message);
     }
     $analysis = array();
     try {
         // PHPCS handles recursion on its own.
         // $analysis = $phpcs->processFiles($module->getLocation());
         // But we have already enumerated the files, so lets keep consistent.
         $tree = $module->getCodeFiles($extensions);
         // $analysis = $phpcs->processFiles($tree);
         // processFiles is too abstract, it doesn't return the individual results.
         // Do the iteration ourselves.
         foreach ($tree as $filepath) {
             /** @var PHP_CodeSniffer_File $analysed */
             $analysed = $phpcs->processFile($filepath);
             $analysis[$filepath] = $analysed;
         }
     } catch (Exception $e) {
         $message = "When processing " . $module->getLocation() . " " . $e->getMessage();
         error_log($message);
     }
     // Params for reporting.
     $report = 'full';
     $showSources = FALSE;
     $cliValues = array('colors' => FALSE);
     $reportFile = 'report.out';
     $result = $phpcs->reporting->printReport($report, $showSources, $cliValues, $reportFile);
     #print_r($result);
     return $analysis;
 }
Esempio n. 16
0
 /**
  * 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);
     }
 }
Esempio n. 17
0
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     if (false !== strpos($phpcsFile->getFilename(), 'model') || false !== strpos($phpcsFile->getFilename(), 'form') || false !== strpos($phpcsFile->getFilename(), 'filter')) {
         return null;
     }
     $tokens = $phpcsFile->getTokens();
     $className = $phpcsFile->findNext(T_STRING, $stackPtr);
     $name = trim($tokens[$className]['content']);
     // "op" prefix
     if (0 !== strpos($name, 'op')) {
         $error = ucfirst($tokens[$stackPtr]['content']) . ' name must begin with "op" prefix';
         $phpcsFile->addError($error, $stackPtr);
     }
     // "Interface" suffix
     if ($tokens[$stackPtr]['code'] === T_INTERFACE && !preg_match('/Interface$/', $name)) {
         $error = ucfirst($tokens[$stackPtr]['content']) . ' name must end with "Interface"';
         $phpcsFile->addError($error, $stackPtr);
     }
     // stripped prefix
     if (0 === strpos($name, 'op')) {
         $name = substr($name, 2);
     }
     if (!PHP_CodeSniffer::isCamelCaps($name, true, true, false)) {
         $error = ucfirst($tokens[$stackPtr]['content']) . ' name is not in camel caps format';
         $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
  * @throws PHP_CodeSniffer_Exception If jshint.js could not be run
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $fileName = $phpcsFile->getFilename();
     $rhinoPath = PHP_CodeSniffer::getConfigData('rhino_path');
     $jshintPath = PHP_CodeSniffer::getConfigData('jshint_path');
     if ($rhinoPath === null || $jshintPath === null) {
         return;
     }
     $cmd = "{$rhinoPath} \"{$jshintPath}\" \"{$fileName}\"";
     $msg = exec($cmd, $output, $retval);
     if (is_array($output) === true) {
         foreach ($output as $finding) {
             $matches = array();
             $numMatches = preg_match('/^(.+)\\(.+:([0-9]+).*:[0-9]+\\)$/', $finding, $matches);
             if ($numMatches === 0) {
                 continue;
             }
             $line = (int) $matches[2];
             $message = 'jshint says: ' . trim($matches[1]);
             $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
         }
     }
     // 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 integer              $stackPtr  The position of the current token in
  *                                        the token stack.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     if ($this->_phpVersion === null) {
         $this->_phpVersion = PHP_CodeSniffer::getConfigData('php_version');
         if ($this->_phpVersion === null) {
             $this->_phpVersion = PHP_VERSION_ID;
         }
     }
     $tokens = $phpcsFile->getTokens();
     if (isset($tokens[$stackPtr]['scope_closer']) === false) {
         return;
     }
     $errorData = array(strtolower($tokens[$stackPtr]['content']));
     $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), $tokens[$stackPtr]['scope_closer'] + 1);
     if ($nextClass !== false) {
         $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 ($this->_phpVersion >= 50300) {
         $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->addError($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)
 {
     $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');
         }
     }
 }
 /**
  * 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);
     }
 }
Esempio n. 22
0
 /**
  * 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();
     $content = $tokens[$stackPtr]['content'];
     if ($content == 'cache_get' || $content == 'cache_set') {
         //$closer = $tokens[$stackPtr + 1]['parenthesis_closer'];
         // The first parameter is the one sensible
         $p1tokens = $utils::get_param_tokens($phpcsFile, $stackPtr, 1);
         if (!$p1tokens) {
             echo "empty {$content}?\n";
             return;
         }
         $closer = end($p1tokens)['stackPtr'] + 1;
         $s = $stackPtr + 1;
         while ($s < $closer) {
             $s = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $s + 1, $closer, true);
             if (!$s) {
                 break;
             }
             if ($utils::is_token_user_input($tokens[$s])) {
                 $phpcsFile->addError("Potential cache injection found in {$content}()", $s, 'D7Cachei');
             } elseif (PHP_CodeSniffer::getConfigData('ParanoiaMode') && in_array($tokens[$s]['code'], $utils::getVariableTokens())) {
                 $phpcsFile->addWarning("Direct variable usage in {$content}()", $s, 'D7CacheDirectVar');
             }
         }
     }
 }
Esempio n. 23
0
 /**
  * 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();
     $trait = $phpcsFile->findNext(T_STRING, $stackPtr);
     $name = $tokens[$trait]['content'];
     if (preg_match('|^[A-Z]|', $name) === 0) {
         $error = 'Each %s name must begin with a capital letter';
         $errorData = array($tokens[$stackPtr]['content']);
         $phpcsFile->addError($error, $stackPtr, 'StartWithCapital', $errorData);
     }
     if ($this->allowUnderscore === true) {
         if (preg_match('|_[a-z]|', $name)) {
             $error = 'Trait "%s" is not in camel caps with underscores format';
             $phpcsFile->addError($error, $stackPtr, 'CamelCapsWithUnderscore', array($name));
         }
         $name = lcfirst(str_replace('_', '', $name));
     } else {
         if (strpos($name, '_') !== FALSE) {
             $error = 'Underscores are not allowed in trait "%s"';
             $phpcsFile->addError($error, $stackPtr, 'NoUnderscore', array($name));
         }
         $name = array(lcfirst($name));
     }
     if (PHP_CodeSniffer::isCamelCaps($name, false, true, true) === false) {
         $error = 'Trait "%s" is not in camel caps format';
         $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', array($name));
     }
 }
Esempio n. 24
0
 /**
  * @param $node
  * @return bool|string
  */
 public function validate($node)
 {
     if ($node instanceof Stmt\Function_) {
         if (!\PHP_CodeSniffer::isCamelCaps($node->name, false, true, true)) {
             return [Logger::LOGLEVEL_ERROR, "Function name is not in camel caps format"];
         }
         return true;
     }
     if ($node instanceof Stmt\ClassMethod) {
         if ($this->isMagicMethod($node->name)) {
             return true;
         }
         if (!\PHP_CodeSniffer::isCamelCaps($node->name, false, true, true)) {
             return [Logger::LOGLEVEL_ERROR, "Method name is not in camel caps format"];
         }
         return true;
     }
     if ($node instanceof Node\Expr\Variable) {
         if (!\PHP_CodeSniffer::isCamelCaps($node->name, false, true, true) && !\PHP_CodeSniffer::isCamelCaps($node->name, true, true, true)) {
             return [Logger::LOGLEVEL_WARNING, "Variable name is not in camel caps format"];
         }
         return true;
     }
     if ($node instanceof Node\Stmt\PropertyProperty) {
         if (!\PHP_CodeSniffer::isCamelCaps($node->name, false, true, true) && !\PHP_CodeSniffer::isCamelCaps($node->name, true, true, true)) {
             return [Logger::LOGLEVEL_WARNING, "Property name is not in camel caps format"];
         }
         return true;
     }
     return true;
 }
 /**
  * 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)
 {
     $fileName = $phpcsFile->getFilename();
     $jslPath = PHP_CodeSniffer::getConfigData('jsl_path');
     if (is_null($jslPath) === true) {
         return;
     }
     $cmd = '"' . $jslPath . '" -nologo -nofilelisting -nocontext -nosummary -output-format __LINE__:__ERROR__ -process "' . $fileName . '"';
     $msg = exec($cmd, $output, $retval);
     // Variable $exitCode is the last line of $output if no error occurs, on
     // error it is numeric. Try to handle various error conditions and
     // provide useful error reporting.
     if ($retval === 2 || $retval === 4) {
         if (is_array($output) === true) {
             $msg = join('\\n', $output);
         }
         throw new PHP_CodeSniffer_Exception("Failed invoking JavaScript Lint, retval was [{$retval}], output was [{$msg}]");
     }
     if (is_array($output) === true) {
         foreach ($output as $finding) {
             $split = strpos($finding, ':');
             $line = substr($finding, 0, $split);
             $message = substr($finding, $split + 1);
             $phpcsFile->addWarningOnLine(trim($message), $line, 'ExternalTool');
         }
     }
     // Ignore the rest of the file.
     return $phpcsFile->numTokens + 1;
 }
Esempio n. 26
0
 private function getTestVersion()
 {
     /**
      * var $testVersion will hold an array containing min/max version of PHP
      *   that we are checking against (see above).  If only a single version
      *   number is specified, then this is used as both the min and max.
      */
     static $arrTestVersions;
     if (!isset($testVersion)) {
         $testVersion = PHP_CodeSniffer::getConfigData('testVersion');
         $testVersion = trim($testVersion);
         $arrTestVersions = array(null, null);
         if (preg_match('/^\\d+\\.\\d+$/', $testVersion)) {
             $arrTestVersions = array($testVersion, $testVersion);
         } elseif (preg_match('/^(\\d+\\.\\d+)\\s*-\\s*(\\d+\\.\\d+)$/', $testVersion, $matches)) {
             if (version_compare($matches[1], $matches[2], ">")) {
                 trigger_error("Invalid range in testVersion setting: '" . $testVersion . "'", E_USER_WARNING);
             } else {
                 $arrTestVersions = array($matches[1], $matches[2]);
             }
         } elseif (!$testVersion == "") {
             trigger_error("Invalid testVersion setting: '" . $testVersion . "'", E_USER_WARNING);
         }
     }
     return $arrTestVersions;
 }
Esempio n. 27
0
 /**
  * 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)
 {
     $phpPath = PHP_CodeSniffer::getConfigData('php_path');
     if ($phpPath === null) {
         return;
     }
     $fileName = $phpcsFile->getFilename();
     $cmd = "{$phpPath} -l \"{$fileName}\" 2>&1";
     $output = shell_exec($cmd);
     $matches = array();
     if (preg_match('/^.*error:(.*) in .* on line ([0-9]+)/', $output, $matches)) {
         $error = trim($matches[1]);
         $line = (int) $matches[2];
         $tokens = $phpcsFile->getTokens();
         $numLines = $tokens[$phpcsFile->numTokens - 1]['line'];
         if ($line > $numLines) {
             $line = $numLines;
         }
         foreach ($tokens as $id => $token) {
             if ($token['line'] === $line) {
                 $phpcsFile->addError("PHP syntax error: {$error}", $id, 'PHPSyntax');
                 break;
             }
         }
     }
 }
 /**
  * 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.
  *
  * @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);
     }
 }
Esempio n. 30
0
 /**
  * Process analysis with framework standard
  * 
  * @param  string $file
  * @see    parent::process()
  * 
  * @return bool
  */
 function process($file)
 {
     $root_dir = CAppUI::conf("root_dir");
     $file = "{$root_dir}/{$file}";
     $standard = $this->getStandardDir();
     parent::process($file, $standard);
 }