Skip to content

Commit

Permalink
Create special case for T_BAD_CHARACTER constant
Browse files Browse the repository at this point in the history
  • Loading branch information
fredden committed Aug 21, 2023
1 parent 4025b08 commit 4eace06
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 15 deletions.
7 changes: 1 addition & 6 deletions PHPCompatibility/Sniffs/Constants/NewConstantsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class NewConstantsSniff extends Sniff
* A list of new PHP Constants, not present in older versions.
*
* The array lists : version number with false (not present) or true (present).
* If's sufficient to list the first version where the constant appears.
* It's sufficient to list the first version where the constant appears.
*
* Note: PHP constants are case-sensitive!
*
Expand Down Expand Up @@ -6802,11 +6802,6 @@ class NewConstantsSniff extends Sniff
'7.3' => false,
'7.4' => true,
],
'T_BAD_CHARACTER' => [
'7.3' => false,
'7.4' => true,
'extension' => 'tokenizer',
],
'T_COALESCE_EQUAL' => [
'7.3' => false,
'7.4' => true,
Expand Down
6 changes: 1 addition & 5 deletions PHPCompatibility/Sniffs/Constants/RemovedConstantsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class RemovedConstantsSniff extends Sniff
* A list of removed PHP Constants.
*
* The array lists : version number with false (deprecated) or true (removed).
* If's sufficient to list the first version where the constant was deprecated/removed.
* It's sufficient to list the first version where the constant was deprecated/removed.
*
* Optional, the array can contain an `alternative` key listing an alternative constant
* to be used instead.
Expand Down Expand Up @@ -1932,10 +1932,6 @@ class RemovedConstantsSniff extends Sniff
'7.0' => true,
'extension' => 'tokenizer',
],
'T_BAD_CHARACTER' => [
'7.0' => true,
'extension' => 'tokenizer',
],
'MSSQL_ASSOC' => [
'7.0' => true,
'extension' => 'mssql',
Expand Down
102 changes: 102 additions & 0 deletions PHPCompatibility/Sniffs/Constants/TemporarilyRemovedConstantsSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

/**
* PHPCompatibility, an external standard for PHP_CodeSniffer.
*
* @package PHPCompatibility
* @copyright 2012-2023 PHPCompatibility Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCompatibility/PHPCompatibility
*/

namespace PHPCompatibility\Sniffs\Constants;

use PHPCompatibility\Helpers\MiscHelper;
use PHPCompatibility\Helpers\ScannedCode;
use PHPCompatibility\Sniff;
use PHP_CodeSniffer\Files\File;
use PHPCSUtils\Utils\MessageHelper;

/**
* Detect use of PHP native global constants which have been removed and re-added.
*
* PHP version All
*
* @since 10.0.0
*/
class TemporarilyRemovedConstantsSniff extends Sniff
{

/**
* A list of removed & re-added PHP Constants.
*
* Note: PHP Constants are case-sensitive!
*
* @since 10.0.0
*
* @var array(string => array(string => string))
*/
protected $constants = [
'T_BAD_CHARACTER' => [
'removed' => '7.0',
'last_absent' => '7.3',
're-added' => '7.4',
],
];

/**
* Returns an array of tokens this test wants to listen for.
*
* @since 10.0.0
*
* @return array
*/
public function register()
{
return [
\T_STRING,
];
}

/**
* Processes this test, when one of its tokens is encountered.
*
* @since 10.0.0
*
* @param 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(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$constantName = $tokens[$stackPtr]['content'];

if (isset($this->constants[$constantName]) === false) {
return;
}

if (MiscHelper::isUseOfGlobalConstant($phpcsFile, $stackPtr) === false) {
return;
}

$itemArray = $this->constants[$constantName];

if (
ScannedCode::shouldRunOnOrAbove($itemArray['removed'])
&& ScannedCode::shouldRunOnOrBelow($itemArray['last_absent'])
) {
$phpcsFile->addError(
'The constant "%s" was removed in PHP %s and re-added in PHP %s.',
$stackPtr,
MessageHelper::stringToErrorCode($constantName, true),
[
$constantName,
$itemArray['removed'],
$itemArray['re-added'],
]
);
}
}
}
2 changes: 1 addition & 1 deletion PHPCompatibility/Tests/Constants/NewConstantsUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ echo TIDY_TAG_TRACK;
echo TIDY_TAG_VIDEO;
echo CURL_VERSION_ALTSVC;
echo CURL_VERSION_CURLDEBUG;
echo T_BAD_CHARACTER;

echo IMG_FILTER_SCATTER;
echo PASSWORD_ARGON2_PROVIDER;
echo SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13;
Expand Down
1 change: 0 additions & 1 deletion PHPCompatibility/Tests/Constants/NewConstantsUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,6 @@ public static function dataNewConstant()
['PASSWORD_ARGON2_PROVIDER', '7.3', 864, '7.4'],
['PHP_WINDOWS_EVENT_CTRL_C', '7.3', 830, '7.4'],
['PHP_WINDOWS_EVENT_CTRL_BREAK', '7.3', 831, '7.4'],
['T_BAD_CHARACTER', '7.3', 862, '7.4'],
['T_COALESCE_EQUAL', '7.3', 1048, '7.4'],
['T_FN', '7.3', 1049, '7.4'],
['TIDY_TAG_ARTICLE', '7.3', 832, '7.4'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ echo IBASE_SVC_GET_USERS;
echo FILTER_SANITIZE_MAGIC_QUOTES;
echo CURLPIPE_HTTP1;
echo T_CHARACTER;
echo T_BAD_CHARACTER;


echo NCURSES_COLOR_BLACK;
echo NCURSES_COLOR_WHITE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,6 @@ public static function dataRemovedConstant()

['PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT', '7.0', 15, '5.6'],
['T_CHARACTER', '7.0', 139, '5.6'],
['T_BAD_CHARACTER', '7.0', 140, '5.6'],
['MSSQL_ASSOC', '7.0', 557, '5.6'],
['MSSQL_NUM', '7.0', 558, '5.6'],
['MSSQL_BOTH', '7.0', 559, '5.6'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
// Constants which were present, then removed, then present again.

/* T_BAD_CHARACTER */
echo T_BAD_CHARACTER; // Constant itself.
echo t_bad_character; // Not the uppercase constant.
echo BAD_CHARACTER; // Not the right constant.
echo My\NS\T_BAD_CHARACTER; // Not the global constant.
echo self::T_BAD_CHARACTER; // Not the global constant.
echo $obj->T_BAD_CHARACTER; // Not a constant.
function T_BAD_CHARACTER() {} // Not a constant.
echo \T_BAD_CHARACTER; // This is the global constant and should be flagged.
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

/**
* PHPCompatibility, an external standard for PHP_CodeSniffer.
*
* @package PHPCompatibility
* @copyright 2012-2023 PHPCompatibility Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCompatibility/PHPCompatibility
*/

namespace PHPCompatibility\Tests\Constants;

use PHPCompatibility\Tests\BaseSniffTestCase;

/**
* Test the ReaddedConstants sniff.
*
* @group constants
* @covers \PHPCompatibility\Sniffs\Constants\TemporarilyRemovedConstantsSniff
* @since 10.0.0
*/
class TemporarilyRemovedConstantsUnitTest extends BaseSniffTestCase
{

/**
* Test re-added constant sniff
*
* @dataProvider dataReaddedConstants
*
* @param string $constantName Name of the PHP constant.
* @param int $line Line number in the test file which applies to this constant.
* @param string $phpVersion PHP version (or range) to test with.
* @param bool $shouldError If we expect to get an error or not from the sniff.
* @param string $removedIn PHP version this feature was removed (for the error string).
* @param string $addedIn PHP version this feature was re-addded (for the error string).
*
* @return void
*/
public function testReaddedConstant($constantName, $line, $phpVersion, $shouldError, $removedIn, $addedIn)
{
$error = "The constant \"$constantName\" was removed in PHP $removedIn and re-added in PHP $addedIn.";

$file = $this->sniffFile(__FILE__, $phpVersion);
if ($shouldError) {
$this->assertError($file, $line, $error);
} else {
$this->assertNoViolation($file, $line);
}
}

/**
* Data provider.
*
* @see testReaddedConstant()
*
* @return array
*/
public static function dataReaddedConstants()
{
// This could be more elegantly written with a generator, but this project supports PHP v5.4 which is before generators were introduced (in PHP 5.5).
return [
['T_BAD_CHARACTER', 5, '5.6', false, '7.0', '7.4'], // Last version before removal
['T_BAD_CHARACTER', 5, '7.0', true, '7.0', '7.4'], // Removed
['T_BAD_CHARACTER', 5, '7.1', true, '7.0', '7.4'], // Removed
['T_BAD_CHARACTER', 5, '7.2', true, '7.0', '7.4'], // Removed
['T_BAD_CHARACTER', 5, '7.3', true, '7.0', '7.4'], // Removed
['T_BAD_CHARACTER', 5, '7.4', false, '7.0', '7.4'], // Added again

['T_BAD_CHARACTER', 5, '-5.6', false, '7.0', '7.4'], // Before
['T_BAD_CHARACTER', 5, '-7.2', true, '7.0', '7.4'], // Inside
['T_BAD_CHARACTER', 5, '-8.2', true, '7.0', '7.4'], // After

['T_BAD_CHARACTER', 5, '5.4-', true, '7.0', '7.4'], // Before
['T_BAD_CHARACTER', 5, '7.2-', true, '7.0', '7.4'], // Inside
['T_BAD_CHARACTER', 5, '7.4-', false, '7.0', '7.4'], // After

['T_BAD_CHARACTER', 5, '5.0-5.6', false, '7.0', '7.4'], // Before
['T_BAD_CHARACTER', 5, '7.4-8.3', false, '7.0', '7.4'], // After
['T_BAD_CHARACTER', 5, '5.0-8.3', true, '7.0', '7.4'], // Inside and both sides
['T_BAD_CHARACTER', 5, '5.0-7.2', true, '7.0', '7.4'], // Inside and before
['T_BAD_CHARACTER', 5, '7.0-7.3', true, '7.0', '7.4'], // Inside only
['T_BAD_CHARACTER', 5, '7.2-8.1', true, '7.0', '7.4'], // Inside and after

// Other cases
['T_BAD_CHARACTER', 6, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 7, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 8, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 9, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 10, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 11, '7.0', false, '7.0', '7.4'],
['T_BAD_CHARACTER', 12, '7.0', true, '7.0', '7.4'],
];
}

/**
* Verify no notices are thrown at all.
*
* @dataProvider dataNoViolations
*
* @param string $phpVersion PHP version to test with.
*
* @return void
*/
public function testNoViolationsInFileOnValidVersion($phpVersion)
{
$file = $this->sniffFile(__FILE__, $phpVersion);
$this->assertNoViolation($file);
}

/**
* Data provider.
*
* @see testNoViolationsInFileOnValidVersion()
*
* @return array
*/
public static function dataNoViolations()
{
return [
['5.0'], // Low version below the first deprecation.
['99.0'], // High version, after all constants have been re-added.
];
}
}

0 comments on commit 4eace06

Please sign in to comment.