*/ public function register() { return [ \T_LNUMBER, ]; } /** * Processes this test, when one of its tokens is encountered. * * @since 7.0.3 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in * the stack. * * @return int|void Integer stack pointer to skip forward or void to continue * normal file processing. */ public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $numberInfo = Numbers::getCompleteNumber($phpcsFile, $stackPtr); if (Numbers::isBinaryInt($numberInfo['content']) === true) { if (ScannedCode::shouldRunOnOrBelow('5.3') === true) { $error = 'Binary integer literals were not present in PHP version 5.3 or earlier. Found: %s'; $data = [$numberInfo['orig_content']]; $phpcsFile->addError($error, $stackPtr, 'BinaryIntegerFound', $data); } if ($this->isInvalidBinaryInteger($tokens, $numberInfo['last_token']) === true) { $error = 'Invalid binary integer detected. Found: %s'; $data = [$this->getBinaryInteger($phpcsFile, $tokens, $stackPtr)]; $phpcsFile->addWarning($error, $stackPtr, 'InvalidBinaryIntegerFound', $data); } // If this was a PHP 7.4 numeric literal, no need to scan subsequent parts of the number again. return $numberInfo['last_token']; } $isError = ScannedCode::shouldRunOnOrAbove('7.0'); $isInvalidOctal = $this->isInvalidOctalInteger($tokens, $stackPtr, $numberInfo); if ($isInvalidOctal !== false) { MessageHelper::addMessage( $phpcsFile, 'Invalid octal integer detected. Prior to PHP 7 this would lead to a truncated number. From PHP 7 onwards this causes a parse error. Found: %s', $stackPtr, $isError, 'InvalidOctalIntegerFound', [$isInvalidOctal] ); } // If this was a PHP 7.4 numeric literal, no need to scan subsequent parts of the number again. return $numberInfo['last_token']; } /** * Is the current token an invalid binary integer ? * * @since 7.0.3 * * @param array $tokens Token stack. * @param int $stackPtr The current position in the token stack. * * @return bool */ private function isInvalidBinaryInteger($tokens, $stackPtr) { $next = $tokens[$stackPtr + 1]; // If it's an invalid binary int, the token will be split into two T_LNUMBER tokens. if ($next['code'] === \T_LNUMBER) { return true; } if ($next['code'] === \T_STRING && \preg_match('`^((? $numberInfo The information on the number to examine * * @return string|bool The invalid octal as a string or false when this is not an invalid octal. */ private function isInvalidOctalInteger($tokens, $stackPtr, $numberInfo) { // For invalid explicit octal, we need to also check the next token. if (($numberInfo['content'] === '0' && \strtolower($tokens[($stackPtr + 1)]['content'][0]) === 'o') || \stripos($numberInfo['content'], '0o') === 0 ) { if (\preg_match('`^(?:[o_][0-7_]*)?[8-9]+[_0-9]*$`iD', $tokens[($stackPtr + 1)]['content']) === 1) { return $tokens[$stackPtr]['content'] . $tokens[($stackPtr + 1)]['content']; } } if (\preg_match('`^0[0-7]*[8-9]+[0-9]*$`iD', $numberInfo['content']) === 1) { return $numberInfo['orig_content']; } return false; } }