@param \PHP_CodeSniffer\Files\File $phpCsFile
@param int $contentIndex

@return array
166610
protected function extractException(File $phpCsFile, int $contentIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $fullClass = '';

        $position = $contentIndex;
        while ($this->isGivenKind([T_NS_SEPARATOR, T_STRING], $tokens[$position])) {
            $fullClass .= $tokens[$position]['content'];
            ++$position;
        }

        $class = $fullClass;
        $lastSeparator = strrpos($class, '\\');
        if ($lastSeparator !== false) {
            $class = substr($class, $lastSeparator + 1);
        }

        return [
            'start' => $contentIndex,
            'end' => $position - 1,
            'fullClass' => $fullClass,
            'class' => $class,
        ];
    }
1188614
protected function needsBrackets(File $phpcsFile, $openingBraceIndex, $closingBraceIndex) {
		$tokens = $phpcsFile->getTokens();

		$whitelistedCodes = [
			T_LNUMBER,
			T_STRING,
			T_BOOL_CAST,
			T_STRING_CAST,
			T_INT_CAST,
			T_ARRAY_CAST,
			T_COMMENT,
			T_WHITESPACE,
			T_VARIABLE,
			T_DOUBLE_COLON,
			T_OBJECT_OPERATOR,
		];

		for ($i = $openingBraceIndex + 1; $i < $closingBraceIndex; $i++) {
			if ($tokens[$i]['type'] === 'T_OPEN_PARENTHESIS') {
				$i = $tokens[$i]['parenthesis_closer'];
				continue;
			}
			if (in_array($tokens[$i]['code'], $whitelistedCodes, false)) {
				continue;
			}

			return true;
		}

		return false;
	}
950546
private function processNewLine(PHP_CodeSniffer_File $phpcsFile, $commentStart)
	{
		$tokens = $phpcsFile->getTokens();

		$prevTag = array();
		$firstTagLine = array('line' => -1);
		foreach ($tokens[$commentStart]['comment_tags'] as $tagIndex) {
			$tag = $tokens[$tagIndex];

			if (!empty($prevTag)) {
				$lineDiff = $tag['line'] - $prevTag['line'];

				// New tag type? And they're not seperated by one empty line? That's our error
				if ($prevTag['type'] != $tag['content']) {
					$lineDiffShouldBe = 2;

					if ($prevTag['type'] == '@param') {
						$nextIndex = $phpcsFile->findNext(
							array(T_DOC_COMMENT_TAG, T_DOC_COMMENT_STRING),
							$prevTag['index'] + 1
						);

						while ($tokens[$nextIndex]['code'] != T_DOC_COMMENT_TAG) {
							$lineDiffShouldBe = $lineDiffShouldBe + $tokens[$nextIndex]['line'] - $prevTag['line'];

							$nextIndex = $phpcsFile->findNext(
								array(T_DOC_COMMENT_TAG, T_DOC_COMMENT_STRING),
								$nextIndex + 1
							);
						}
					}

					if ($lineDiff != $lineDiffShouldBe) {
						$error = 'There should be exactly one new line between different tag types';
						$phpcsFile->addError($error, $tagIndex, 'MissingNewLine');
					}
				}
			}

			if ($firstTagLine['line'] == -1 || $tag['line'] < $firstTagLine['line']) {
				$firstTagLine = array(
					'line' => $tag['line'],
					'index' => $tagIndex
				);
			}

			$prevTag = array(
				'type' => $tag['content'],
				'line' => $tag['line'],
				'index' => $tagIndex
			);
		}

		// No tag? Only comment then, nothing to do
		if ($firstTagLine['line'] == -1) {
			return;
		}

		$internalFirstLine = $firstTagLine['line'] - $tokens[$commentStart]['line'];

		// The first tag is on the first comment line so we don't need to check other things
		if ($internalFirstLine == 1) {
			return;
		}

		$previousStringIndex = $phpcsFile->findPrevious(T_DOC_COMMENT_STRING, $firstTagLine['index']);

		// The comment is somewhere but not two lines above the firsttag
		if ($tokens[$previousStringIndex]['line'] != $firstTagLine['line'] - 2) {
			$error = 'There should be exactly one new line between different tag types';
			$phpcsFile->addError($error, $tagIndex, 'MissingNewLine');
		}
	}
769482
public function process(File $phpcsFile, $stackPtr) {
		$utils = \PHPCS_SecurityAudit\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\Util\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');
			}
		}

	}
617821
public function process(File $phpcsFile, $stackPtr) {

		$utils = \PHPCS_SecurityAudit\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\Util\Tokens::$bracketTokens, \PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHP_CodeSniffer\Util\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\Util\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\Config::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');
				}
			}
		}
	}
1233506
public function process(File $phpcsFile, $stackPtr) {
		$utils = new 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\Config::getConfigData('ParanoiaMode')) {
				$phpcsFile->addWarning('drupal_http_request called with variable ' . $tokens[$d]['content'], $stackPtr, 'D7HttpRequestUserInputErr');
			}

		}
	}
365143
public function process(File $phpcsFile, $stackPtr)
    {
        if ($this->supportsBelow('5.6') !== true) {
            return;
        }

        $tokens = $phpcsFile->getTokens();

        $ignore = array(
            \T_DOUBLE_COLON    => true,
            \T_OBJECT_OPERATOR => true,
            \T_FUNCTION        => true,
            \T_CONST           => true,
        );

        $prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
        if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
            // Not a call to a PHP function.
            return;
        }

        $functionLc = strtolower($tokens[$stackPtr]['content']);
        if ($functionLc !== 'define') {
            return;
        }

        $secondParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 2);
        if (isset($secondParam['start'], $secondParam['end']) === false) {
            return;
        }

        $targetNestingLevel = 0;
        if (isset($tokens[$secondParam['start']]['nested_parenthesis'])) {
            $targetNestingLevel = \count($tokens[$secondParam['start']]['nested_parenthesis']);
        }

        $array = $phpcsFile->findNext(array(\T_ARRAY, \T_OPEN_SHORT_ARRAY), $secondParam['start'], ($secondParam['end'] + 1));
        if ($array !== false) {
            if ((isset($tokens[$array]['nested_parenthesis']) === false && $targetNestingLevel === 0) || \count($tokens[$array]['nested_parenthesis']) === $targetNestingLevel) {
                $phpcsFile->addError(
                    'Constant arrays using define are not allowed in PHP 5.6 or earlier',
                    $array,
                    'Found'
                );
            }
        }
    }
1032288
protected function getFixableMethodAnnotations(File $phpCsFile, int $docBlockStartIndex, int $docBlockEndIndex): array
    {
        $tokens = $phpCsFile->getTokens();

        $path = $this->findBasePath($phpCsFile->getFilename());
        if (!$path) {
            // We cannot fix it then for now
            return [];
        }

        $annotations = [];
        for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
            if ($tokens[$i]['code'] !== T_DOC_COMMENT_TAG || $tokens[$i]['content'] !== '@method') {
                continue;
            }

            // T_DOC_COMMENT_STRING invalid, another sniff should check on this
            if (strpos($tokens[$i + 2]['content'], ' ') === false) {
                continue;
            }

            [$class, $method] = explode(' ', $tokens[$i + 2]['content'], 2);

            $ignoredMethods = [
                'getFactory()',
                'getConfig()',
                'getSharedConfig()',
                'getApplication()',
            ];
            if (in_array($method, $ignoredMethods, true)) {
                continue;
            }

            if (substr($class, -9) === 'Interface' || substr($class, 0, 5) === '\\Orm\\') {
                continue;
            }
            if (!preg_match('/^[A-Z]/', $class)) {
                continue;
            }
            if ($this->isAbstract($class)) {
                continue;
            }

            $interface = $class . 'Interface';
            $interfacePathElement = str_replace('\\', DIRECTORY_SEPARATOR, $interface);
            $interfacePath = $path . $interfacePathElement . '.php';

            if (!file_exists($interfacePath)) {
                $phpCsFile->addError(
                    sprintf('Interface missing for %s annotation of %s', $method, $class),
                    $i,
                    'Annotation.Interface.Missing'
                );
                continue;
            }

            $annotation = [
                'index' => $i,
                'method' => $method,
                'class' => $class,
                'interface' => $interface,
            ];

            $annotations[] = $annotation;
        }

        return $annotations;
    }
406016
protected function isEllipsis(File $phpcsFile, int $variableIndex): bool
    {
        $tokens = $phpcsFile->getTokens();

        $prevIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, $variableIndex - 1, null, true);
        if (!defined('T_ELLIPSIS')) {
            return $tokens[$prevIndex]['content'] === '.';
        }

        return $this->isGivenKind(T_ELLIPSIS, $tokens[$prevIndex]);
    }
391402
protected function processCategory(PHP_CodeSniffer_File $phpcsFile, array $tags)
    {
        $tokens = $phpcsFile->getTokens();

        foreach ($tags as $tag)
        {
            if ($tokens[($tag + 2)]['code'] !== T_DOC_COMMENT_STRING)
            {
                // No content.
                continue;
            }

            $content = $tokens[($tag + 2)]['content'];

            if (PHP_CodeSniffer::isUnderscoreName($content) !== true)
            {
                $newContent = str_replace(' ', '_', $content);
                $nameBits   = explode('_', $newContent);
                $firstBit   = array_shift($nameBits);
                $newName    = ucfirst($firstBit) . '_';

                foreach ($nameBits as $bit)
                {
                    if ($bit !== '')
                    {
                        $newName .= ucfirst($bit) . '_';
                    }
                }

                $error     = 'Category name "%s" is not valid; consider "%s" instead';
                $validName = trim($newName, '_');
                $data      = [
                              $content,
                              $validName,
                             ];
                $phpcsFile->addError($error, $tag, 'InvalidCategory', $data);
            }
        }//end foreach
    }
952822
protected function addSpace(File $phpcsFile, int $index): void
    {
        if ($phpcsFile->fixer->enabled !== true) {
            return;
        }
        $phpcsFile->fixer->addContent($index, ' ');
    }
822100
protected function parseImplements(File $phpcsFile, int $implementsStartIndex): array
    {
        $implementsEndIndex = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, $implementsStartIndex + 1);

        return $this->parse($phpcsFile, $implementsStartIndex, $implementsEndIndex);
    }
321806
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens     = $phpcsFile->getTokens();
        $functionLc = strtolower($tokens[$stackPtr]['content']);
        if (isset($this->targetFunctions[$functionLc]) === false) {
            return;
        }

        // Next non-empty token should be the open parenthesis.
        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
        if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
            return;
        }

        $ignore = array(
            \T_DOUBLE_COLON    => true,
            \T_OBJECT_OPERATOR => true,
            \T_FUNCTION        => true,
            \T_NEW             => true,
        );

        $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
        if (isset($ignore[$tokens[$prevNonEmpty]['code']]) === true) {
            // Not a call to a PHP function.
            return;
        } elseif ($tokens[$prevNonEmpty]['code'] === \T_NS_SEPARATOR && $tokens[$prevNonEmpty - 1]['code'] === \T_STRING) {
            // Namespaced function.
            return;
        }

        $data = $tokens[$stackPtr]['content'];

        /*
         * Check for usage of the functions in the global scope.
         *
         * As PHPCS can not determine whether a file is included from within a function in
         * another file, so always throw a warning/error.
         */
        if ($phpcsFile->hasCondition($stackPtr, array(\T_FUNCTION, \T_CLOSURE)) === false) {
            $isError = false;
            $message = 'Use of %s() outside of a user-defined function is only supported if the file is included from within a user-defined function in another file prior to PHP 5.3.';

            if ($this->supportsAbove('5.3') === true) {
                $isError  = true;
                $message .= ' As of PHP 5.3, it is no longer supported at all.';
            }

            $this->addMessage($phpcsFile, $message, $stackPtr, $isError, 'OutsideFunctionScope', $data);
        }

        /*
         * Check for usage of the functions as a parameter in a function call.
         */
        if ($this->supportsBelow('5.2') === false) {
            return;
        }

        if (isset($tokens[$stackPtr]['nested_parenthesis']) === false) {
            return;
        }

        $throwError = false;

        $closer = end($tokens[$stackPtr]['nested_parenthesis']);
        if (isset($tokens[$closer]['parenthesis_owner'])
            && $tokens[$tokens[$closer]['parenthesis_owner']]['type'] === 'T_CLOSURE'
        ) {
            $throwError = true;
        } else {
            $opener       = key($tokens[$stackPtr]['nested_parenthesis']);
            $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true);
            if ($tokens[$prevNonEmpty]['code'] !== \T_STRING) {
                return;
            }

            $prevPrevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevNonEmpty - 1), null, true);
            if ($tokens[$prevPrevNonEmpty]['code'] === \T_FUNCTION) {
                return;
            }

            $throwError = true;
        }

        if ($throwError === false) {
            return;
        }

        $phpcsFile->addError(
            '%s() could not be used in parameter lists prior to PHP 5.3.',
            $stackPtr,
            'InParameterList',
            $data
        );
    }
720320
protected function isTypehintedNullableVariable(File $phpcsFile, int $index): bool
    {
        $tokens = $phpcsFile->getTokens();

        $nextIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $index + 1, null, true);

        $nextToken = $tokens[$nextIndex];

        /*
        if (!$nextToken->equals([T_STRING, 'null'], false)) {
            return false;
        }

        $variableIndex = $tokens->getPrevMeaningfulToken($index);

        $searchTokens = [',', '(', [T_STRING], [CT_ARRAY_TYPEHINT]];
        $typehintKinds = [T_STRING, CT_ARRAY_TYPEHINT];

        if (defined('T_CALLABLE')) {
            $searchTokens[] = [T_CALLABLE];
            $typehintKinds[] = T_CALLABLE;
        }

        $prevIndex = $tokens->getPrevTokenOfKind($variableIndex, $searchTokens);

        return $tokens[$prevIndex]->isGivenKind($typehintKinds);
        */
        return false;
    }
253738
protected function clearWhitespacesBeforeIndex(File $phpcsFile, int $index): void
    {
        $tokens = $phpcsFile->getTokens();

        if ($tokens[$index - 1]['code'] !== T_WHITESPACE) {
            return;
        }

        $phpcsFile->fixer->replaceToken($index - 1, '');
    }
560210
public function process(File $phpcsFile, $stackPtr)
    {
        $tokens    = $phpcsFile->getTokens();
        $tokenType = $tokens[$stackPtr]['type'];

        // Detect incorrectly tokenized binary casts.
        if (isset($this->newTypeCasts[$tokenType]) === false) {
            $tokenContent = $tokens[$stackPtr]['content'];
            switch ($tokenType) {
                case 'T_STRING_CAST':
                    if (preg_match('`^\(\s*binary\s*\)$`i', $tokenContent) !== 1) {
                        return;
                    }

                    $tokenType = 'T_BINARY_CAST';
                    break;

                case 'T_CONSTANT_ENCAPSED_STRING':
                    if ((strpos($tokenContent, 'b"') === 0 && substr($tokenContent, -1) === '"')
                        || (strpos($tokenContent, "b'") === 0 && substr($tokenContent, -1) === "'")
                    ) {
                        $tokenType = 'T_BINARY_CAST';
                    } else {
                        return;
                    }
                    break;

            }
        }

        // If the translation did not yield one of the tokens we are looking for, bow out.
        if (isset($this->newTypeCasts[$tokenType]) === false) {
            return;
        }

        $itemInfo = array(
            'name'    => $tokenType,
            'content' => $tokens[$stackPtr]['content'],
        );
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
    }
1144128
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        if ($this->supportsAbove('5.5')) {
            $tokens = $phpcsFile->getTokens();

            if ($tokens[$stackPtr]['content'] == "preg_replace") {
                $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);

                /**
                 * If argument is not a string, then skip test (e.g. if variable passed in).
                 */
                if ($tokens[$firstParam]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
                    return;
                }

                /**
                 * Regex is a T_CONSTANT_ENCAPSED_STRING, so we need to remove the quotes
                 */
                $regex = "";
                while (isset($tokens[$firstParam]) && $tokens[$firstParam]['code'] != T_COMMA) {
                    if ($tokens[$firstParam]['code'] == T_CONSTANT_ENCAPSED_STRING) {
                        $regex .= $tokens[$firstParam]['content'];
                    }
                    $firstParam++;
                }

                $regex = substr($regex, 1, -1);

                $regexFirstChar = substr($regex, 0, 1);
                $regexEndPos = strrpos($regex, $regexFirstChar);

                $modifiers = substr($regex, $regexEndPos + 1);

                if (strpos($modifiers, "e") !== false) {
                    $error = 'preg_replace() - /e modifier is deprecated in PHP 5.5';
                    $phpcsFile->addError($error, $stackPtr);
                }
            }
        }


    }