Validates whether a file does not contain a closing php tag

@param	string	$originFile		File to validate
@return	null
971240
public function validateNoPhpClosingTag($originFile)
	{
		$fileContents = (string) file_get_contents($this->originPath . '/' . $originFile);
		$fileContents = str_replace("\r\n", "\n", $fileContents);
		$fileContents = str_replace("\r", "\n", $fileContents);

		// Does the file contain anything after the last ");"
		if (substr($fileContents, -3) !== ");\n")
		{
			if (substr($fileContents, -3) !== "];\n")
			{
				$this->output->addMessage(Output::FATAL, 'File must not contain a PHP closing tag, but end with one new line', $originFile);
			}
		}
	}
1353218
public function validate()
	{
		$sourceFiles = $this->getFileList($this->sourcePath);
		// License file is required but missing from en/, so we add it here
		$sourceFiles[] = $this->sourceLanguagePath . 'LICENSE';
		$sourceFiles = array_unique($sourceFiles);

		// Get $lang['direction'] of translation to allow additional rtl-files for rtl-translations
		$filePath = $this->originPath . '/' . $this->originLanguagePath . 'common.php';

		if ($this->safeMode)
		{
			$lang = ValidatorRunner::langParser($filePath);
		}

		else
		{
			include($filePath);
		}

		$direction = $lang['DIRECTION'];
		// Throw error, if invalid direction is used
		if (!in_array($direction, array('rtl', 'ltr')))
		{
			$this->output->addMessage(Output::FATAL, 'DIRECTION needs to be rtl or ltr');
		}

		$originFiles = $this->getFileList($this->originPath);

		$missingSubsilver2Files = $availableSubsilver2Files = array();
		$validFiles = array();
		foreach ($sourceFiles as $sourceFile)
		{
			$testOriginFile = str_replace('/' . $this->sourceIso . '/', '/' . $this->originIso . '/', $sourceFile);
			if (!in_array($testOriginFile, $originFiles))
			{
				$this->output->addMessage(Output::FATAL, 'Missing required file', $testOriginFile);
			}
			else if (substr($sourceFile, -4) != '.gif' && substr($sourceFile, -12) != 'imageset.cfg')
			{
				$validFiles[$sourceFile] = $testOriginFile;
			}
		}

		foreach ($originFiles as $origin_file)
		{
			$testSourceFile = str_replace('/' . $this->originIso . '/', '/' . $this->sourceIso . '/', $origin_file);
			if (!in_array($testSourceFile, $sourceFiles))
			{
				if (in_array($origin_file, array(
					$this->originLanguagePath . 'AUTHORS.md',
					$this->originLanguagePath . 'CHANGELOG.md',
					$this->originLanguagePath . 'README.md',
					$this->originLanguagePath . 'VERSION.md',
				)))
				{
					$this->output->addMessage(Output::NOTICE, 'Found additional file', $origin_file);
				}
				else
				{
					if (substr($origin_file, -10) === '/index.htm' || $origin_file === 'index.htm')
					{
						$level = Output::NOTICE;
					}
					else if ($this->phpbbVersion === '3.2' && strpos($origin_file, 'styles/subsilver2/') === 0)
					{
						$level = Output::FATAL;
					}
					else if (in_array(substr($origin_file, -4), array('.gif', '.png')) && $direction === 'rtl')
					{
						$level = Output::WARNING;
					}
					else if (substr($origin_file, -3) !==	'.md')
					{
						$level = Output::FATAL;
					}
					else
					{
						$level = Output::ERROR;
					}

					$this->output->addMessage($level, 'Found additional file', $origin_file);
				}

				if (substr($origin_file, -14) === '/site_logo.gif')
				{
					$this->output->addMessage(Output::FATAL, 'Found additional file', $origin_file);
				}
			}
		}

		return $validFiles;
	}
1014610
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

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

        if (isset($tokens[$stackPtr]['parenthesis_opener']) === true) {
            $parenOpener = $tokens[$stackPtr]['parenthesis_opener'];
            $parenCloser = $tokens[$stackPtr]['parenthesis_closer'];

            if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE
                && !$this->isNextTokenAnException($tokens, $parenOpener + 1)
            ) {
                $gap   = strlen($tokens[($parenOpener + 1)]['content']);
                $error = 'Expected 0 spaces after opening bracket; %s found';
                $data  = array($gap);
                $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data);
            }

            if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']
                && $tokens[($parenCloser - 1)]['code'] === T_WHITESPACE
            ) {
                $gap   = strlen($tokens[($parenCloser - 1)]['content']);
                $error = 'Expected 0 spaces before closing bracket; %s found';
                $data  = array($gap);
                $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data);
            }
        }//end if

        $scopeOpener = $tokens[$stackPtr]['scope_opener'];
        $scopeCloser = $tokens[$stackPtr]['scope_closer'];

        $firstContent = $phpcsFile->findNext(
            T_WHITESPACE,
            ($scopeOpener + 1),
            null,
            true
        );

        if ($tokens[$firstContent]['line'] !== ($tokens[$scopeOpener]['line'] + 1)) {
            $error = 'Blank line found at start of control structure';
            $phpcsFile->addError($error, $scopeOpener, 'SpacingBeforeOpen');
        }

        $lastContent = $phpcsFile->findPrevious(
            T_WHITESPACE,
            ($scopeCloser - 1),
            null,
            true
        );

        if ($tokens[$lastContent]['line'] !== ($tokens[$scopeCloser]['line'] - 1)) {
            $errorToken = $scopeCloser;
            for ($i = ($scopeCloser - 1); $i > $lastContent; $i--) {
                if ($tokens[$i]['line'] < $tokens[$scopeCloser]['line']) {
                    $errorToken = $i;
                    break;
                }
            }

            $error = 'Blank line found at end of control structure';
            $phpcsFile->addError($error, $errorToken, 'SpacingAfterClose');
        }

        $trailingContent = $phpcsFile->findNext(
            T_WHITESPACE,
            ($scopeCloser + 1),
            null,
            true
        );

        if ($tokens[$trailingContent]['code'] === T_ELSE) {
            if ($tokens[$stackPtr]['code'] === T_IF) {
                // IF with ELSE.
                return;
            }
        }

        if ($tokens[$trailingContent]['code'] === T_COMMENT) {
            if ($tokens[$trailingContent]['line'] === $tokens[$scopeCloser]['line']) {
                if (substr($tokens[$trailingContent]['content'], 0, 5) === '//end') {
                    // There is an end comment, so we have to get the next piece
                    // of content.
                    $trailingContent = $phpcsFile->findNext(
                        T_WHITESPACE,
                        ($trailingContent + 1),
                        null,
                        true
                    );
                }
            }
        }

        // If this token is closing a CASE or DEFAULT, we don't need the
        // blank line after this control structure.
        if (isset($tokens[$trailingContent]['scope_condition']) === true) {
            $condition = $tokens[$trailingContent]['scope_condition'];
            if ($tokens[$condition]['code'] === T_CASE
                || $tokens[$condition]['code'] === T_DEFAULT
            ) {
                return;
            }
        }

        if ($tokens[$trailingContent]['code'] === T_CLOSE_TAG) {
            // At the end of the script or embedded code.
            return;
        }

        if ($tokens[$trailingContent]['code'] === T_CLOSE_CURLY_BRACKET) {
            // Another control structure's closing brace.
            if (isset($tokens[$trailingContent]['scope_condition']) === true) {
                $owner = $tokens[$trailingContent]['scope_condition'];
                if ($tokens[$owner]['code'] === T_FUNCTION) {
                    // The next content is the closing brace of a function
                    // so normal function rules apply and we can ignore it.
                    return;
                }
            }

            if ($tokens[$trailingContent]['line'] !== ($tokens[$scopeCloser]['line'] + 1)) {
                $error = 'Blank line found after control structure';
                $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose');
            }
        } else {
            if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) {
                $error = 'No blank line found after control structure';
                $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose');
            }
        }

    }
455149
public function validateDefinedInPhpbb($originFile)
	{
		$fileContents = (string) file_get_contents($this->originPath . '/' . $originFile);

		// Regex copied from MPV
		if (!preg_match("#defined([ ]+){0,1}\\(([ ]+){0,1}'IN_PHPBB'#", $fileContents))
		{
			$this->output->addMessage(Output::FATAL, 'Must check whether IN_PHPBB is defined', $originFile);
		}
	}
16591
protected function assertNoSpacing(File $phpCsFile, array $first, array $second): void
    {
        $tokens = $phpCsFile->getTokens();

        $lastIndexOfFirst = $first['tagEnd'];
        $lastLineOfFirst = $tokens[$lastIndexOfFirst]['line'];

        $tagIndexOfSecond = $second['index'];
        $firstLineOfSecond = $tokens[$tagIndexOfSecond]['line'];

        if ($lastLineOfFirst === $firstLineOfSecond - 1) {
            return;
        }

        $fix = $phpCsFile->addFixableError('No newline expected between tags of the same type `' . $first['tag'] . '`', $tagIndexOfSecond, 'NoNewlineBetweenSameType');
        if (!$fix) {
            return;
        }

        $phpCsFile->fixer->beginChangeset();

        for ($i = $first['tagEnd'] + 1; $i < $second['start']; $i++) {
            if ($tokens[$i]['line'] <= $lastLineOfFirst || $tokens[$i]['line'] >= $firstLineOfSecond) {
                continue;
            }

            $phpCsFile->fixer->replaceToken($i, '');
        }

        $phpCsFile->fixer->endChangeset();
    }
198948
public function processClose(File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();

        // Just in case.
        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
            return;
        }

        $closeBrace = $tokens[$stackPtr]['scope_closer'];
        if ($tokens[($closeBrace - 1)]['code'] === T_WHITESPACE) {
            $prevContent = $tokens[($closeBrace - 1)]['content'];
            if ($prevContent !== $phpcsFile->eolChar) {
                $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar));
                $spaces     = strlen($blankSpace);
                if ($spaces !== 0) {
                    if ($tokens[($closeBrace - 1)]['line'] !== $tokens[$closeBrace]['line']) {
                        $error = 'Expected 0 spaces before closing brace; newline found';
                        $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'NewLineBeforeCloseBrace');
                    } else {
                        $error = 'Expected 0 spaces before closing brace; %s found';
                        $data  = array($spaces);
                        $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpaceBeforeCloseBrace', $data);
                    }//end if

                    if ($fix === true) {
                        $phpcsFile->fixer->beginChangeset();
                        $phpcsFile->fixer->replaceToken(($closeBrace - 1), '');
                        $phpcsFile->fixer->endChangeset();
                    }
                }//end if
            }//end if
        }//end if

        // Check that the closing brace has one blank line after it.
        $nextContent = $phpcsFile->findNext(array(T_WHITESPACE), ($closeBrace + 1), null, true);
        if ($nextContent !== false) {
            $difference = ($tokens[$nextContent]['line'] - $tokens[$closeBrace]['line'] - 1);
            if ($difference < 0) {
                $difference = 0;
            }

            if ($difference !== 1) {
                $error = 'Closing brace of a %s must be followed by a single blank line; found %s';
                $data  = array(
                          $tokens[$stackPtr]['content'],
                          $difference,
                         );
                $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'NewlinesAfterCloseBrace', $data);
                if ($fix === true) {
                    $phpcsFile->fixer->beginChangeset();

                    if ($difference > 1) {
                        for ($i = ($closeBrace + 1); $i < $nextContent; $i++) {
                            if ($tokens[$i]['line'] === $tokens[$nextContent]['line']) {
                                // Keep existing indentation.
                                break;
                            }

                            $phpcsFile->fixer->replaceToken($i, '');
                        }
                    }

                    $phpcsFile->fixer->addNewline($closeBrace);
                    $phpcsFile->fixer->endChangeset();
                }
            }//end if
        }//end if
    }
96432
public function validateOrigin($origin)
    {
        if (empty($origin)) {
            $this->addError('origin', 'Origin cannot be empty');
            return false;
        }

        if (!in_array($origin, array('http', 'cli', 'cron'))) {
            $this->addError('origin', 'Origin must be either "http", "cli" or "cron"');
            return false;
        }

        return true;
    }
573093
protected function insideSwitchCase(File $phpcsFile, $stackPtr)
    {
        if ($this->isScopeCondition($phpcsFile, $stackPtr, array(T_CASE, T_DEFAULT)) === true) {
            $tokens = $phpcsFile->getTokens();

            // Consider "return" instead of "break" as function ending to enforce empty line before it.
            return $tokens[$stackPtr]['code'] !== T_RETURN;
        }

        return false;
    }
902510
public function validateCSSFile($sourceFile, $originFile)
	{
		$sourceFileContents = (string) file_get_contents($this->sourcePath . '/' . $sourceFile);
		$originFileContents = (string) file_get_contents($this->originPath . '/' . $originFile);

		$sourceRules = $this->getCSSRules($sourceFile, $sourceFileContents);
		$originRules = $this->getCSSRules($originFile, $originFileContents);

		$missingRules = array_diff(array_keys($sourceRules), array_keys($originRules));
		$additionalRules = array_diff(array_keys($originRules), array_keys($sourceRules));
		if (!empty($missingRules))
		{
			$this->output->addMessage(Output::FATAL, 'Stylesheet file is missing CSS rules: ' . implode(', ', $missingRules), $originFile);
		}
		if (!empty($additionalRules))
		{
			$this->output->addMessage(Output::FATAL, 'Stylesheet file has additional CSS rules: ' . implode(', ', $additionalRules), $originFile);
		}
	}
26756
protected function validateEntityIdFile()
    {
        $field = 'entity_id';

        if ($this->isExcluded($field)) {
            return null;
        }

        $value = $this->getSubmitted($field);

        if (!isset($value)) {
            $this->unsetSubmitted($field);
            return null;
        }

        $label = $this->translation->text('Entity ID');

        if (!is_numeric($value)) {
            $this->setErrorInteger($field, $label);
            return false;
        }

        if (strlen($value) > 10) {
            $this->setErrorLengthRange($field, $label, 0, 10);
            return false;
        }

        return true;
    }
848178
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();
        $token = $tokens[$stackPtr];
        $length = 0;
        if (isset($token['scope_opener']) === false) {
            //ignore empty methods
            return;
        }

        //get the full length of the method
        $firstToken = $tokens[$token['scope_opener']];
        $lastToken = $tokens[$token['scope_closer']];
        $length = $lastToken['line'] - $firstToken['line'];

        if ($length > $this->absoluteMaxLength) {
            $error = sprintf("Method's length (%d) exceeds maximum length of %d", $length, $this->absoluteMaxLength);
            $phpcsFile->addError($error, $stackPtr, 'MethodTooBig');
            return;
        }

        if ($length > $this->maxLength) {
            $error = sprintf("Method's length (%d) exceeds %d, consider refactoring", $length, $this->maxLength);
            $phpcsFile->addWarning($error, $stackPtr, 'MethodTooBig');
        }
    }
1191132
public function validateReCaptchaValue($originFile, $validate)
	{
		// The key 'RECAPTCHA_LANG' must match the list provided by Google, or be left empty
		// If any other key is used, we will show an error
		if (array_key_exists('RECAPTCHA_LANG', $validate) && !in_array($validate['RECAPTCHA_LANG'], $this->reCaptchaLanguages))
		{
			// The supplied value doesn't match the allowed values
			$this->output->addMessage(Output::ERROR, 'reCaptcha must match a language/country code on https://developers.google.com/recaptcha/docs/language - if no code exists for your language you can use "en" or leave the string empty', $originFile, 'RECAPTCHA_LANG');
		}
	}
14266
protected function checkAnnotationTagGrouping(File $phpCsFile, int $docBlockStartIndex, int $docBlockEndIndex): void
    {
        $tags = $this->readTags($phpCsFile, $docBlockStartIndex, $docBlockEndIndex);

        $currentTag = null;
        foreach ($tags as $i => $tag) {
            if ($currentTag === null) {
                $currentTag = $tag['tag'];
                continue;
            }

            if ($currentTag === $tag['tag'] || strpos($tag['tag'], $currentTag) === 0) {
                $this->assertNoSpacing($phpCsFile, $tags[$i - 1], $tag);
                continue;
            }

            $this->assertSpacing($phpCsFile, $tags[$i - 1], $tag);
            $currentTag = $tag['tag'];
        }
    }
150305
protected function doGet($sourceFile, $destinationFile)
    {
        $connection = $this->connection;
        $ftpMode = $this->getParam('transfer_mode');
        $createMask = $this->getParam('create_mask');

        return $this->retry(function () use ($connection, $destinationFile, $sourceFile, $ftpMode, $createMask) {
            $localDir = dirname($destinationFile);

            if (!file_exists($localDir)) {
                mkdir($localDir, $createMask, true);
            }

            $res = @ftp_get($connection, $destinationFile, $sourceFile, $ftpMode);

            if (false === $res) {
                throw new \RuntimeException("Couldn't copy file: ".$sourceFile);
            }
        });
    }
584067
public function process(File $phpcsFile, $stackPtr) {
		$tokens = $phpcsFile->getTokens();
		if ($tokens[$stackPtr]['content'] == 'xml_parse_into_struct') {
			$closer = $tokens[$stackPtr + 1]['parenthesis_closer'];
			$s = $stackPtr + 1; // to skip the parenthesis opener '('
						$s = $phpcsFile->findNext(array_merge(\PHP_CodeSniffer\Util\Tokens::$emptyTokens, \PHPCS_SecurityAudit\Sniffs\Utils::$staticTokens), $s + 1, $closer, true);
			if ($s) {
				$phpcsFile->addWarning('CVE-2013-4113 ext/xml/xml.c in PHP before 5.3.27 does not properly consider parsing depth, which allows remote attackers to cause a denial of service (heap memory corruption) or possibly have unspecified other impact via a crafted document that is processed by the xml_parse_into_struct function.', $stackPtr, 'CVE-2013-4113');
				if ($tokens[$s]['code'] == T_DOUBLE_QUOTED_STRING) {
					echo $tokens[$s]['content'];
				}
			}
		}
	}
988169
protected function processAuthor(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'];
			$local   = '\da-zA-Z-_+';

			// Dot character cannot be the first or last character in the local-part.
			$localMiddle = $local . '.\w';

			if (preg_match(
				'/^([^<]*)\s+<([' . $local . ']([' . $localMiddle . ']*[' . $local . '])*@[\da-zA-Z][-.\w]*[\da-zA-Z]\.[a-zA-Z]{2,7})>$/',
				$content
			) === 0)
			{
				$error = 'Content of the @author tag must be in the form "Display Name <username@example.com>"';
				$phpcsFile->addError($error, $tag, 'InvalidAuthors');
			}
		}
	}
826320
public function findFirstOnLine(File $phpcsFile, $start)
    {
        $tokens = $phpcsFile->getTokens();

        for ($i = $start; $i >= 0; $i--) {
            if ($tokens[$i]['line'] === $tokens[$start]['line']) {
                continue;
            }

            return ($i + 1);
        }

        return false;
    }