findNext() public method

If a value is specified, the next token of the specified type(s) containing the specified value will be returned. Returns false if no token can be found.
See also: findPrevious()
public findNext ( integer | array $types, integer $start, integer $end = null, boolean $exclude = false, string $value = null, boolean $local = false ) : integer | boolean
$types integer | array The type(s) of tokens to search for.
$start integer The position to start searching from in the token stack.
$end integer The end position to fail if no token is found. if not specified or null, end will default to the end of the token stack.
$exclude boolean If true, find the next token that is NOT of a type specified in $types.
$value string The value that the token(s) must be equal to. If value is omitted, tokens with any value will be returned.
$local boolean If true, tokens outside the current statement will not be checked. i.e., checking will stop at the next semi-colon found.
return integer | 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 ($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 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();
     // Find the content of each style definition name.
     $end = $tokens[$stackPtr]['bracket_closer'];
     $next = $phpcsFile->findNext(T_STYLE, $stackPtr + 1, $end);
     if ($next === false) {
         // Class definition is empty.
         return;
     }
     $styleNames = array();
     while ($next !== false) {
         $name = $tokens[$next]['content'];
         if (isset($styleNames[$name]) === true) {
             $first = $styleNames[$name];
             $error = 'Duplicate style definition found; first defined on line %s';
             $data = array($tokens[$first]['line']);
             $phpcsFile->addError($error, $next, 'Found', $data);
         } else {
             $styleNames[$name] = $next;
         }
         $next = $phpcsFile->findNext(T_STYLE, $next + 1, $end);
     }
     //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();
     // Check if the next non whitespace token is a string.
     $index = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$index]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
         return;
     }
     // Make sure it is the only thing in the square brackets.
     $next = $phpcsFile->findNext(T_WHITESPACE, $index + 1, null, true);
     if ($tokens[$next]['code'] !== T_CLOSE_SQUARE_BRACKET) {
         return;
     }
     // Allow indexes that have dots in them because we can't write
     // them in dot notation.
     $content = trim($tokens[$index]['content'], '"\' ');
     if (strpos($content, '.') !== false) {
         return;
     }
     // Also ignore reserved words.
     if ($content === 'super') {
         return;
     }
     // Token before the opening square bracket cannot be a var name.
     $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
     if ($tokens[$prev]['code'] === T_STRING) {
         $error = 'Object indexes must be written in dot notation';
         $phpcsFile->addError($error, $prev, '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();
     // 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 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 single-line calls.
  *
  * @param PHP_CodeSniffer_File $phpcsFile   The file being scanned.
  * @param int                  $stackPtr    The position of the current token
  *                                          in the stack passed in $tokens.
  * @param int                  $openBracket The position of the opening bracket
  *                                          in the stack passed in $tokens.
  * @param array                $tokens      The stack of tokens that make up
  *                                          the file.
  *
  * @return void
  */
 public function isMultiLineCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $tokens)
 {
     // If the first argument is on a new line, this is a multi-line
     // function call, even if there is only one argument.
     $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $openBracket + 1, null, true);
     if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
         return true;
     }
     $closeBracket = $tokens[$openBracket]['parenthesis_closer'];
     $end = $phpcsFile->findEndOfStatement($openBracket + 1);
     while ($tokens[$end]['code'] === T_COMMA) {
         // If the next bit of code is not on the same line, this is a
         // multi-line function call.
         $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $end + 1, $closeBracket, true);
         if ($next === false) {
             return false;
         }
         if ($tokens[$next]['line'] !== $tokens[$end]['line']) {
             return true;
         }
         $end = $phpcsFile->findEndOfStatement($next);
     }
     // We've reached the last argument, so see if the next content
     // (should be the close bracket) is also on the same line.
     $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $end + 1, $closeBracket, true);
     if ($next !== false && $tokens[$next]['line'] !== $tokens[$end]['line']) {
         return true;
     }
     return false;
 }
 /**
  * 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_CASE && isset($tokens[$stackPtr]['scope_closer'])) {
         //			$internalCase = $phpcsFile->findNext(T_CASE, $stackPtr + 1, $tokens[$stackPtr]['scope_closer']);
         //			if ($internalCase !== false) {
         //				$comment = $phpcsFile->findNext(T_COMMENT, $stackPtr + 1, $internalCase - 1);
         //				if ($comment === false) {
         //					$phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.5.12') . '"case" has not break and has not any comment', $stackPtr);
         //				}
         //			}
         $switch = $phpcsFile->findPrevious(T_SWITCH, $stackPtr - 1);
         if ($switch !== false) {
             $nextCase = $phpcsFile->findNext(array(T_CASE, T_DEFAULT), $stackPtr + 1, $tokens[$switch]['scope_closer']);
             if ($nextCase !== false) {
                 $prevBreak = $phpcsFile->findPrevious(T_BREAK, $nextCase - 1, $stackPtr);
                 if ($prevBreak !== false) {
                     $breakWS = $phpcsFile->findNext(T_WHITESPACE, $prevBreak + 1, $nextCase - 1);
                     if ($breakWS !== false) {
                         $str = $phpcsFile->getTokensAsString($breakWS, $nextCase - $breakWS - 1);
                         if (!preg_match("/^\n\n[ ]*\$/Ss", $str)) {
                             $breakWS = false;
                         }
                     }
                     if ($breakWS === false) {
                         $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.5.14') . '"case" must has empty line between current "case" and previous "break"', $stackPtr);
                     }
                 }
             }
         }
     } elseif ($tokens[$stackPtr]['code'] === T_DEFAULT) {
     }
 }
 /**
  * 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 ($this->supportsAbove('5.4')) {
         $tokens = $phpcsFile->getTokens();
         $nextSemicolonToken = $phpcsFile->findNext(T_SEMICOLON, $stackPtr, null, false);
         for ($curToken = $stackPtr + 1; $curToken < $nextSemicolonToken; $curToken++) {
             $gotError = false;
             if ($tokens[$curToken]['type'] == 'T_STRING') {
                 // If the next non-whitespace token after the string
                 // is an opening parenthesis then it's a function call.
                 $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $curToken + 1, null, true);
                 if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
                     continue;
                 } else {
                     $gotError = true;
                 }
             }
             switch ($tokens[$curToken]['type']) {
                 case 'T_VARIABLE':
                 case 'T_FUNCTION':
                     $gotError = true;
                     break;
             }
             if ($gotError === true) {
                 $error = 'Using a variable argument on break or continue is forbidden since PHP 5.4';
                 $phpcsFile->addError($error, $stackPtr);
             }
         }
     }
 }
 /**
  * Processes the tokens that this sniff is interested in.
  *
  * @param PHP_CodeSniffer_File $phpcs_file The file where the token was found.
  * @param int                  $stack_ptr  The position in the stack where the token was found.
  *
  * @return void
  */
 public function process(\PHP_CodeSniffer_File $phpcs_file, $stack_ptr)
 {
     // only check for use statements that are before the first class declaration
     // classes can have use statements for traits, for which we are not interested in this sniff
     $first_class_occurence = $phpcs_file->findPrevious([T_CLASS, T_TRAIT], $stack_ptr);
     if ($first_class_occurence > 0 && $stack_ptr > $first_class_occurence) {
         return;
     }
     $tokens = $phpcs_file->getTokens();
     // Reach the end of the current statement
     $stack_ptr = $phpcs_file->findNext([T_SEMICOLON], $stack_ptr + 1);
     $end_stmt = $stack_ptr;
     // if there is another 'use' statement, it should be at $stack_ptr + 1
     $next_use = $phpcs_file->findNext([T_USE], $stack_ptr + 1);
     $next_class = $phpcs_file->findNext([T_CLASS, T_TRAIT], $stack_ptr + 1);
     //There is a class and the next use statement is afte the class definition. skipp it
     if ($next_class && $next_use > $next_class) {
         return;
     }
     //Loop from the end of the use statement (;) untill the next use statement
     for ($i = $end_stmt + 1; $i <= $next_use; $i++) {
         //the current token ($i) contains an end of line
         //And it's on the next line than the end of the use satement
         if (stristr($tokens[$i]['content'], "\n") !== false && $tokens[$i]['line'] != $tokens[$end_stmt]['line']) {
             $this->checkForNewlineOrComments($phpcs_file, $i);
         }
     }
 }
 /**
  * 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');
             }
         }
     }
 }
Example #11
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)
 {
     $tokens = $phpcsFile->getTokens();
     $next_var = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($next_var && $tokens[$next_var]["type"] == "T_STRING") {
         $name_var = $tokens[$next_var]["content"];
         $var_line = $tokens[$next_var]["line"];
         $next = $phpcsFile->findNext(T_WHITESPACE, $next_var + 1, null, true);
         $error = false;
         $only_one = "'Var' statement must contain only one variable";
         if ($tokens[$stackPtr]["line"] != $var_line) {
             $error = "'Var' statement must be on one line";
         } elseif ($tokens[$next]["type"] == "T_SEMICOLON") {
             $error = "Variable '{$name_var}' must be initialized";
         } elseif ($tokens[$next]["type"] == "T_COMMA") {
             $error = $only_one;
         }
         if ($error === false) {
             do {
                 $next_var = $phpcsFile->findNext(T_WHITESPACE, $next_var + 1, null, true);
                 $token = $tokens[$next_var];
             } while ($token["line"] == $var_line && !in_array($token["type"], array("T_COMMA", "T_SEMICOLON", "T_OPEN_SQUARE_BRACKET")));
             if ($token["type"] == "T_COMMA") {
                 $error = $only_one;
             }
         }
         if ($error !== false) {
             $phpcsFile->addError($this->getReqPrefix('REQ.JS.3.7') . $error, $stackPtr);
         }
     }
     return;
 }
Example #12
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)
 {
     // If short open tags are off, then any short open tags will be converted
     // to inline_html tags so we can just ignore them.
     // If its on, then we want to ban the use of them.
     $option = ini_get('short_open_tag');
     // Ini_get returns a string "0" if short open tags is off.
     if ($option === '0') {
         return;
     }
     if (!isset($this->files_cache[$phpcsFile->getFilename()]) && !$phpcsFile->findNext(T_OPEN_TAG, $stackPtr + 1) && !$phpcsFile->findNext(T_OPEN_TAG_WITH_ECHO, $stackPtr + 1) && $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr)) {
         $error = 'Файл имеет только один открывающий PHP-тэг, но имеет закрывающий PHP-тэг.';
         $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.1.1') . $error, $stackPtr);
     }
     $this->files_cache[$phpcsFile->getFilename()] = true;
     $tokens = $phpcsFile->getTokens();
     $openTag = $tokens[$stackPtr];
     if ($openTag['content'] === '<?') {
         $error = 'Short PHP opening tag used. Found "' . $openTag['content'] . '" Expected "<?php".';
         $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.1.2') . $error, $stackPtr);
     }
     if ($openTag['code'] === T_OPEN_TAG_WITH_ECHO) {
         $nextVar = $tokens[$phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true)];
         $error = 'Short PHP opening tag used with echo. Found "';
         $error .= $openTag['content'] . ' ' . $nextVar['content'] . ' ..." but expected "<?php echo ' . $nextVar['content'] . ' ...".';
         $phpcsFile->addError($this->getReqPrefix('REQ.PHP.2.1.2') . $error, $stackPtr);
     }
 }
Example #13
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)
 {
     $tokens = $phpcsFile->getTokens();
     $style = $tokens[$stackPtr]['content'];
     $start = $phpcsFile->findNext(T_COLON, $stackPtr);
     $end = $phpcsFile->findNext(T_SEMICOLON, $stackPtr);
     if (!$start || !$end) {
         return;
     }
     # Get the full description value
     $value = '';
     for ($i = $start + 1; $i < $end; $i++) {
         if ($tokens[$i]['code'] === T_LNUMBER) {
             # Next to number follows the dimension
             if ($tokens[$i + 1]['code'] === T_WHITESPACE || $tokens[$i + 1]['code'] === T_SEMICOLON) {
                 continue;
             }
             $dim = $tokens[$i + 1]['content'];
             if (!in_array($dim, $this->allowedDims)) {
                 $error = 'Запрещены к использованию размерности, кроме px, em, ex, %';
                 $phpcsFile->addError($this->getReqPrefix('REQ.CSS.3.0.1') . $error, $i);
             } elseif (in_array($style, $this->relativeDimsStyles) && !in_array($dim, array('em', 'ex', '%'))) {
                 /* TODO - research
                                   $error = 'Размерность шрифта требуется задавать в em/ex';
                                   $phpcsFile->addError($this->getReqPrefix('REQ.CSS.3.0.1') . $error, $i);
                 			*/
             }
         }
     }
 }
Example #14
0
 /**
  * @inheritdoc
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $classScopeStart = $tokens[$stackPtr]['scope_opener'];
     $classScopeEnd = $tokens[$stackPtr]['scope_closer'];
     $classPosition = $stackPtr;
     $stackPtr = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
     $className = $tokens[$stackPtr]['content'];
     if (false === ($stackPtr = $phpcsFile->findNext(T_EXTENDS, $stackPtr + 1))) {
         // the currently tested class hasn't extended any class
         return;
     }
     $stackPtr = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
     $parentClassName = $tokens[$stackPtr]['content'];
     if ($parentClassName == self::PARENT_CLASS_NAME) {
         while (false !== ($stackPtr = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $classScopeStart + 1, $classScopeEnd - 1, true, 'function'))) {
             $stackPtr = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
             $methodName = $tokens[$stackPtr]['content'];
             $classScopeStart = $stackPtr;
             if ($methodName == self::REQUIRED_ACL_METHOD_NAME) {
                 // the currently tested class has implemented the required ACL method
                 return;
             }
         }
         $phpcsFile->addError('Missing the %s() ACL method in the %s class.', $classPosition, 'MissingAclMethod', array(self::REQUIRED_ACL_METHOD_NAME, $className));
     }
 }
 /**
  * Process this function definition.
  *
  * @param PHP_CodeSniffer_File $phpcsFile   The file being scanned.
  * @param int                  $stackPtr    The position of the function name in the stack.
  *                                           name in the stack.
  * @param int                  $functionPtr The position of the function keyword in the stack.
  *                                           keyword in the stack.
  *
  * @return void
  */
 public function processFunction(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $functionPtr)
 {
     $fileExtension = strtolower(substr($phpcsFile->getFilename(), -6));
     // Only check in *.module files.
     if ($fileExtension !== 'module') {
         return;
     }
     $fileName = substr(basename($phpcsFile->getFilename()), 0, -7);
     $tokens = $phpcsFile->getTokens();
     if ($tokens[$stackPtr]['content'] !== $fileName . '_menu') {
         return;
     }
     // Search in the function body for t() calls.
     $string = $phpcsFile->findNext(T_STRING, $tokens[$functionPtr]['scope_opener'], $tokens[$functionPtr]['scope_closer']);
     while ($string !== false) {
         if ($tokens[$string]['content'] === 't') {
             $opener = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $string + 1, null, true);
             if ($opener !== false && $tokens[$opener]['code'] === T_OPEN_PARENTHESIS) {
                 $error = 'Do not use t() in hook_menu()';
                 $phpcsFile->addError($error, $string, 'TFound');
             }
         }
         $string = $phpcsFile->findNext(T_STRING, $string + 1, $tokens[$functionPtr]['scope_closer']);
     }
     //end while
 }
 /**
  * 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();
     if ($this->forceParanoia >= 0) {
         $parano = $this->forceParanoia ? 1 : 0;
     } else {
         $parano = PHP_CodeSniffer::getConfigData('ParanoiaMode') ? 1 : 0;
     }
     $tokens = $phpcsFile->getTokens();
     $s = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr, null, true, null, true);
     if ($tokens[$stackPtr]['code'] == T_OPEN_TAG_WITH_ECHO) {
         $closer = $phpcsFile->findNext(T_CLOSE_TAG, $stackPtr);
     } elseif ($tokens[$s]['code'] == T_OPEN_PARENTHESIS) {
         $closer = $tokens[$s]['parenthesis_closer'];
     } else {
         $closer = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), $stackPtr);
         $s = $stackPtr;
     }
     $warn = false;
     while ($s) {
         $s = $phpcsFile->findNext(array_merge(PHP_CodeSniffer_Tokens::$emptyTokens, PHP_CodeSniffer_Tokens::$bracketTokens, Security_Sniffs_Utils::$staticTokens), $s + 1, $closer, true);
         if ($s && $utils::is_token_user_input($tokens[$s])) {
             $phpcsFile->addError('Easy XSS detected because of direct user input with ' . $tokens[$s]['content'] . ' on ' . $tokens[$stackPtr]['content'], $s, 'EasyXSSerr');
         } elseif ($s && $utils::is_XSS_mitigation($tokens[$s]['content'])) {
             $s = $tokens[$s + 1]['parenthesis_closer'];
         } elseif ($s && $parano && !$warn) {
             $warn = $s;
         }
     }
     if ($warn) {
         $phpcsFile->addWarning('Possible XSS detected with ' . $tokens[$warn]['content'] . ' on ' . $tokens[$stackPtr]['content'], $warn, 'EasyXSSwarn');
     }
 }
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $nameIndex = $phpcsFile->findNext(T_VARIABLE, $stackPtr + 1);
     $semicolonIndex = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1);
     while ($nameIndex < $semicolonIndex) {
         if ($tokens[$nameIndex]['code'] !== T_WHITESPACE && $tokens[$nameIndex]['code'] !== T_COMMA) {
             $globalName = $tokens[$nameIndex]['content'];
             if (in_array($globalName, $this->ignoreList) || in_array($globalName, self::$PHPReserved)) {
                 return;
             }
             // Skip '$' and forge a valid global variable name
             $expected = '$wg' . ucfirst(substr($globalName, 1));
             // Verify global is prefixed with wg
             if (strpos($globalName, '$wg') !== 0) {
                 $phpcsFile->addError('Global variable "%s" is lacking \'wg\' prefix. Should be "%s".', $stackPtr, 'wgPrefix', array($globalName, $expected));
             } else {
                 // Verify global is probably CamelCase
                 $val = ord(substr($globalName, 3, 1));
                 if (!($val >= 65 && $val <= 90)) {
                     $phpcsFile->addError('Global variable "%s" should use CamelCase: "%s"', $stackPtr, 'CamelCase', array($globalName, $expected));
                 }
             }
         }
         $nameIndex++;
     }
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  * @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();
     $line = $tokens[$stackPtr]['line'];
     while ($tokens[$stackPtr]['line'] == $line) {
         /*
          * Suffix traits with Trait;
          */
         if ('T_TRAIT' == $tokens[$stackPtr]['type']) {
             $name = $phpcsFile->findNext(T_STRING, $stackPtr);
             if ($name && substr($tokens[$name]['content'], -5) != 'Trait') {
                 $phpcsFile->addError('Trait name is not suffixed with "Trait"', $stackPtr, 'InvalidTraitName');
             }
             break;
         }
         /*
          * Suffix exceptions with Exception;
          */
         if ('T_EXTENDS' == $tokens[$stackPtr]['type']) {
             $extend = $phpcsFile->findNext(T_STRING, $stackPtr);
             if ($extend && substr($tokens[$extend]['content'], -9) == 'Exception') {
                 $class = $phpcsFile->findPrevious(T_CLASS, $stackPtr);
                 $name = $phpcsFile->findNext(T_STRING, $class);
                 if ($name && substr($tokens[$name]['content'], -9) != 'Exception') {
                     $phpcsFile->addError('Exception name is not suffixed with "Exception"', $stackPtr, 'InvalidExceptionName');
                 }
             }
             break;
         }
         $stackPtr++;
     }
     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();
     $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)
 {
     if (is_null(PHP_CodeSniffer::getConfigData('testVersion')) || !is_null(PHP_CodeSniffer::getConfigData('testVersion')) && version_compare(PHP_CodeSniffer::getConfigData('testVersion'), '5.4') >= 0) {
         $tokens = $phpcsFile->getTokens();
         if (in_array($tokens[$stackPtr]['content'], $this->algoFunctions) === true) {
             $openBracket = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true);
             if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
                 return;
             }
             $firstParam = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $openBracket + 1, null, true);
             /**
              * Algorithm is a T_CONSTANT_ENCAPSED_STRING, so we need to remove the quotes
              */
             $algo = strtolower($tokens[$firstParam]['content']);
             $algo = substr($algo, 1, strlen($algo) - 2);
             switch ($algo) {
                 case 'salsa10':
                 case 'salsa20':
                     $error = 'The Salsa10 and Salsa20 hash algorithms have been removed since PHP 5.4';
                     $phpcsFile->addError($error, $stackPtr);
                     break;
             }
         }
     }
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile
  * @param int $stackPtr
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     $functionToken = $phpcsFile->findNext(T_FUNCTION, $stackPtr);
     if ($functionToken === false) {
         return;
     }
     $nameToken = $phpcsFile->findNext(T_STRING, $functionToken);
     if (in_array($tokens[$nameToken]['content'], $this->magicMethods) === false) {
         return;
     }
     $scopeToken = $phpcsFile->findPrevious(array(T_PUBLIC, T_PROTECTED, T_PRIVATE), $nameToken, $stackPtr);
     if ($scopeToken === false) {
         return;
     }
     if ($tokens[$scopeToken]['type'] != 'T_PUBLIC') {
         $error = "Magic methods must be public (since PHP 5.3) !";
         $phpcsFile->addError($error, $stackPtr);
     }
     $staticToken = $phpcsFile->findPrevious(T_STATIC, $scopeToken, $scopeToken - 2);
     if ($staticToken === false) {
         return;
     } else {
         $error = "Magic methods can not be static (since PHP 5.3) !";
         $phpcsFile->addError($error, $stackPtr);
     }
 }
 /**
  * Process the tokens that this sniff is listening for.
  *
  * @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();
     // Make sure there is a variable before it.
     $variable = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 1, null, true);
     if ($variable === false || $tokens[$variable]['code'] !== T_VARIABLE) {
         return;
     }
     $ignore = array('$_SERVER', '$_GET', '$_POST', '$_REQUEST');
     $variableName = $tokens[$variable]['content'];
     if (in_array($variableName, $ignore) === true) {
         return;
     }
     // We are only interested in indexes that are single strings.
     $index = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true);
     $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $index + 1, null, true);
     if ($next !== $tokens[$stackPtr]['bracket_closer']) {
         return;
     }
     $indexContent = trim($tokens[$index]['content'], "'");
     if (preg_match('|^[a-zA-Z0-9_]+$|', $indexContent) === 1) {
         if (strtolower($indexContent) !== $indexContent) {
             $error = 'Array index "' . $indexContent . '" should not contain uppercase characters';
             $phpcsFile->addError($error, $index);
         }
     }
 }
Example #23
0
 /**
  * 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');
         }
     }
 }
 /**
  * Process the sniff. Will be engaged when one of the tokens from ::register() is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile An instance of the current source file being scanned.
  * @param int $stackPtr The position of the encountered token in the provided file.
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $tokens = $phpcsFile->getTokens();
     // Nothing to do if the file is already in the global namespace.
     if ($phpcsFile->findPrevious(T_NAMESPACE, $stackPtr) === false) {
         return;
     }
     // Only proceed with checking the matched namespaced string if is not part of a `namespace Vendor\Foo;` or a `use Vendor\Bar as Baz;` statement.
     if ($phpcsFile->findPrevious([T_NAMESPACE, T_USE], $stackPtr - 1, null, false, null, true) === false) {
         $nextNonClassSegment = $phpcsFile->findNext([T_NS_SEPARATOR, T_STRING], $stackPtr + 1, null, true);
         $lastNsSeperator = $phpcsFile->findPrevious(T_NS_SEPARATOR, $nextNonClassSegment);
         // Only report for the last backslash matched in a single namespace string. (This sniff will trigger on each slash from `new \Some\Vendor\Lib();`, so this makes sure we don't report 3 errors for that same statement.)
         if ($lastNsSeperator === $stackPtr) {
             $start = $phpcsFile->findPrevious([T_NS_SEPARATOR, T_STRING], $stackPtr - 1, null, true) + 1;
             $end = $phpcsFile->findNext([T_NS_SEPARATOR, T_STRING], $start + 1, null, true);
             $class = '';
             for ($i = $start; $i < $end; $i++) {
                 $class .= $tokens[$i]['content'];
             }
             $tClass = $phpcsFile->findPrevious(T_CLASS, $stackPtr - 1);
             // Check if the code is attempting to extend a class with the same name.
             if ($tClass !== false) {
                 $newClass = $phpcsFile->findNext(T_STRING, $tClass);
                 if ($tokens[$newClass]['content'] == $tokens[$end - 1]['content']) {
                     return;
                 }
                 $err = 'Namespaced class (%s) must be imported before use.';
                 $data = [$class];
                 $phpcsFile->addError($err, $stackPtr, 'ClassMustBeImported', $data);
             }
         }
     }
 }
Example #25
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();
     $firstContent = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     // If the first non-whitespace token is not an opening parenthesis, then we are not concerned.
     if ($tokens[$firstContent]['code'] !== T_OPEN_PARENTHESIS) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     $end = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), $stackPtr, null, false);
     // If the token before the semi-colon is not a closing parenthesis, then we are not concerned.
     $prev = $phpcsFile->findPrevious(T_WHITESPACE, $end - 1, null, true);
     if ($tokens[$prev]['code'] !== T_CLOSE_PARENTHESIS) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     // If the parenthesis don't match, then we are not concerned.
     if ($tokens[$firstContent]['parenthesis_closer'] !== $prev) {
         $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'no');
         return;
     }
     $phpcsFile->recordMetric($stackPtr, 'Brackets around echoed strings', 'yes');
     if ($phpcsFile->findNext(PHP_CodeSniffer_Tokens::$operators, $stackPtr, $end, false) === false) {
         // There are no arithmetic operators in this.
         $error = 'Echoed strings should not be bracketed';
         $fix = $phpcsFile->addFixableError($error, $stackPtr, 'HasBracket');
         if ($fix === true) {
             $phpcsFile->fixer->beginChangeset();
             $phpcsFile->fixer->replaceToken($firstContent, '');
             $phpcsFile->fixer->replaceToken($end - 1, '');
             $phpcsFile->fixer->endChangeset();
         }
     }
 }
 /**
  * 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();
     $start = $tokens[$stackPtr]['scope_opener'];
     $end = $tokens[$stackPtr]['scope_closer'];
     $properties = array();
     $wantedTokens = array(T_PROPERTY, T_OPEN_CURLY_BRACKET);
     $next = $phpcsFile->findNext($wantedTokens, $start + 1, $end);
     while ($next !== false && $next < $end) {
         // Skip nested objects.
         if ($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET) {
             $next = $tokens[$next]['bracket_closer'];
         } else {
             $propName = $tokens[$next]['content'];
             if (isset($properties[$propName]) === true) {
                 $line = $tokens[$properties[$propName]]['line'];
                 $error = "Duplicate property definition found for \"{$propName}\"; previously defined on line {$line}";
                 $phpcsFile->addError($error, $next);
             }
             $properties[$propName] = $next;
         }
         //end if
         $next = $phpcsFile->findNext($wantedTokens, $next + 1, $end);
     }
     //end while
 }
 /**
  * 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 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);
     }
 }
 /**
  * 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();
     if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) {
         $error = 'Expected 1 space before opening brace of class definition; 0 found';
         $phpcsFile->addError($error, $stackPtr, 'NoneBefore');
     } else {
         $content = $tokens[$stackPtr - 1]['content'];
         if ($content !== ' ') {
             $length = strlen($content);
             if ($length === 1) {
                 $length = 'tab';
             }
             $error = 'Expected 1 space before opening brace of class definition; %s found';
             $data = array($length);
             $phpcsFile->addError($error, $stackPtr, 'Before', $data);
         }
     }
     //end if
     $end = $tokens[$stackPtr]['bracket_closer'];
     // Do not check nested style definitions as, for example, in @media style rules.
     $nested = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPtr + 1, $end);
     if ($nested !== false) {
         return;
     }
     $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr + 1, null, true);
     if ($next !== false && $tokens[$next]['line'] !== $tokens[$stackPtr]['line'] + 1) {
         $error = 'Expected exactly one new line after opening brace of class definition';
         $phpcsFile->addError($error, $stackPtr, 'After');
     }
 }