diff --git a/typo3/sysext/backend/Classes/Toolbar/Enumeration/InformationStatus.php b/typo3/sysext/backend/Classes/Toolbar/Enumeration/InformationStatus.php index 14f0ee1443ed3da49a7428300de1b1808c6c8cb9..b1f8fe61e2fe7667dbf94b47226e4737d7bc6caa 100644 --- a/typo3/sysext/backend/Classes/Toolbar/Enumeration/InformationStatus.php +++ b/typo3/sysext/backend/Classes/Toolbar/Enumeration/InformationStatus.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Backend\Toolbar\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This class holds the severities of the SystemInformation toolbar menu */ -class InformationStatus extends \TYPO3\CMS\Core\Type\Enumeration +final class InformationStatus extends Enumeration { const __default = self::STATUS_INFO; diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php index 4703f79088aa95099fe978814e966012c27045e1..54a693d247565fe5d22c3643bf814b8386b5b4ac 100644 --- a/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php +++ b/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\DataHandling; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * Enumeration object for tca internal type */ -class TableColumnSubType extends \TYPO3\CMS\Core\Type\Enumeration +final class TableColumnSubType extends Enumeration { const __default = self::DEFAULT_TYPE; diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php index 92f5a27fea801d45790be1d0ba4285c13e9575a3..4d07d982661a52b78ec6419857f26dd261e4aa76 100644 --- a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php +++ b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\DataHandling; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * Enumeration object for tca type */ -class TableColumnType extends \TYPO3\CMS\Core\Type\Enumeration +final class TableColumnType extends Enumeration { const __default = self::INPUT; diff --git a/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php b/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php index 13ce9e6bb789241b376315c983df3ddb632bc3f7..93a520602414c4d380ae81bfee8a4ac0df125264 100644 --- a/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php +++ b/typo3/sysext/core/Classes/Resource/DuplicationBehavior.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Resource; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * Enumeration object for DuplicationBehavior */ -class DuplicationBehavior extends \TYPO3\CMS\Core\Type\Enumeration +final class DuplicationBehavior extends Enumeration { const __default = self::CANCEL; diff --git a/typo3/sysext/core/Classes/Type/Bitmask/JsConfirmation.php b/typo3/sysext/core/Classes/Type/Bitmask/JsConfirmation.php index b0a7d73a99bf0ed3185479457d6f2f157294f427..09c04d90a15d05eb5197c88cd1d3b9467af9ec2b 100644 --- a/typo3/sysext/core/Classes/Type/Bitmask/JsConfirmation.php +++ b/typo3/sysext/core/Classes/Type/Bitmask/JsConfirmation.php @@ -20,7 +20,7 @@ use TYPO3\CMS\Core\Type\Exception; /** * A class providing constants for bitwise operations on javascript confirmation popups */ -class JsConfirmation extends Enumeration +final class JsConfirmation extends Enumeration { /** * @var int diff --git a/typo3/sysext/core/Classes/Type/Bitmask/Permission.php b/typo3/sysext/core/Classes/Type/Bitmask/Permission.php index 30ec4f6969f53d75916c3e2c573ed44e9e8e93c5..86f55cd19c0c554f5233764f7e7793c0373cc97f 100644 --- a/typo3/sysext/core/Classes/Type/Bitmask/Permission.php +++ b/typo3/sysext/core/Classes/Type/Bitmask/Permission.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Type\Bitmask; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * A class providing constants for bitwise operations on page access check */ -class Permission extends \TYPO3\CMS\Core\Type\Enumeration +final class Permission extends Enumeration { /** * @var int diff --git a/typo3/sysext/core/Classes/Type/Icon/IconState.php b/typo3/sysext/core/Classes/Type/Icon/IconState.php index 45041049434f2cfa0e7ed67462b607f6891f0706..897fd583611e95fe6c04f516fb7f3bdf8b97cb8f 100644 --- a/typo3/sysext/core/Classes/Type/Icon/IconState.php +++ b/typo3/sysext/core/Classes/Type/Icon/IconState.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Type\Icon; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * A class providing constants for icon states */ -class IconState extends \TYPO3\CMS\Core\Type\Enumeration +final class IconState extends Enumeration { const __default = self::STATE_DEFAULT; diff --git a/typo3/sysext/core/Classes/Versioning/VersionState.php b/typo3/sysext/core/Classes/Versioning/VersionState.php index 456a945e48124a0a99361d246c9ab73cb463aadc..d08e22de6ee39e2c7e326329a77cbea086753274 100644 --- a/typo3/sysext/core/Classes/Versioning/VersionState.php +++ b/typo3/sysext/core/Classes/Versioning/VersionState.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Versioning; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * Enumeration object for VersionState */ -class VersionState extends \TYPO3\CMS\Core\Type\Enumeration +final class VersionState extends Enumeration { const __default = self::DEFAULT_STATE; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-85025-EnumerationsAreNowFinal.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-85025-EnumerationsAreNowFinal.rst new file mode 100644 index 0000000000000000000000000000000000000000..c402b42dbe064fb51d825739183f42af0affc89f --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-85025-EnumerationsAreNowFinal.rst @@ -0,0 +1,36 @@ +.. include:: ../../Includes.txt + +============================================= +Breaking: #85025 - Enumerations are now final +============================================= + +See :issue:`85025` + +Description +=========== + +All enumeration classes in TYPO3 have been marked as :php:`final` which prevents extension by 3rd party code. + +By definition an enumeration is a limited and known set of values, any code which uses enumeration relies on this fact. If an enumeration was extended by 3rd party code undefined behavior would occur. For this reason no enumerations must be extended. + +Developers of 3rd party extensions are also encouraged to mark their enumerations as :php:`final`. + + +Impact +====== + +Classes extending TYPO3 enumerations will trigger a fatal PHP error. + + +Affected Installations +====================== + +Instances with classes extending TYPO3 enumerations. + + +Migration +========= + +Remove the classes which extend TYPO3 enumerations. + +.. index:: PHP-API, NotScanned \ No newline at end of file diff --git a/typo3/sysext/core/Tests/Unit/Type/EnumerationTest.php b/typo3/sysext/core/Tests/Unit/Type/EnumerationTest.php index 45b1629832bcd7720860407edb53d950062ab6dd..2cfe1019a5beb46ad2973f062ccb27bd09181c8d 100644 --- a/typo3/sysext/core/Tests/Unit/Type/EnumerationTest.php +++ b/typo3/sysext/core/Tests/Unit/Type/EnumerationTest.php @@ -94,149 +94,44 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase new Enumeration\DuplicateConstantValueEnumeration(1); } - /** - * @test - */ - public function loadValuesSetsStaticEnumConstants() - { - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'] - ); - - $enumClassName = get_class($enumeration); - - $expectedValue = [ - 'INTEGER_VALUE' => 1, - 'STRING_VALUE' => 'foo', - '__default' => 1 - ]; - - $result = $enumeration->_getStatic('enumConstants'); - $this->assertArrayHasKey($enumClassName, $result); - $this->assertSame($expectedValue, $result[$enumClassName]); - } - - /** - * @test - */ - public function constructorSetsValue() - { - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - [1] - ); - $this->assertEquals(1, $enumeration->_get('value')); - } - - /** - * @test - */ - public function setValueSetsValue() - { - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - [1] - ); - $enumeration->_call('setValue', 'foo'); - $this->assertEquals('foo', $enumeration->_get('value')); - } - - /** - * @test - */ - public function setValueToAnInvalidValueThrowsException() - { - $this->expectException(InvalidEnumerationValueException::class); - $this->expectExceptionCode(1381615295); - - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - [1] - ); - $enumeration->_call('setValue', 2); - $this->assertEquals(2, $enumeration->_get('value')); - } - /** * Array of value pairs and expected comparison result */ - public function isValidComparisonExpectations() + public function looseEnumerationValues() { return [ [ 1, - 1, - true - ], - [ - 1, - '1', - true + Enumeration\CompleteEnumeration::INTEGER_VALUE, ], [ '1', - 1, - true + Enumeration\CompleteEnumeration::INTEGER_VALUE, ], [ - 'a1', - 1, - false + 2, + Enumeration\CompleteEnumeration::STRING_INTEGER_VALUE, ], [ - 1, - 'a1', - false - ], - [ - '1a', - 1, - false + '2', + Enumeration\CompleteEnumeration::STRING_INTEGER_VALUE, ], [ - 1, - '1a', - false - ], - [ - 'foo', 'foo', - true + Enumeration\CompleteEnumeration::STRING_VALUE, ], - [ - 'foo', - 'bar', - false - ], - [ - 'foo', - 'foobar', - false - ] ]; } /** * @test - * @dataProvider isValidComparisonExpectations + * @dataProvider looseEnumerationValues */ - public function isValidDoesTypeLooseComparison($enumerationValue, $testValue, $expectation) + public function doesTypeLooseComparison($testValue, $expectedValue) { - $mockName = $this->getUniqueId('CompleteEnumerationMock'); - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - [], - $mockName, - false - ); - $enumeration->_setStatic('enumConstants', [$mockName => ['CONSTANT_NAME' => $enumerationValue]]); - $enumeration->_set('value', $enumerationValue); - $this->assertSame($expectation, $enumeration->_call('isValid', $testValue)); + $value = new Enumeration\CompleteEnumeration($testValue); + + $this->assertEquals((string)$expectedValue, (string)$value); } /** @@ -244,7 +139,13 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase */ public function getConstantsReturnsArrayOfPossibleValuesWithoutDefault() { - $this->assertEquals(['INTEGER_VALUE' => 1, 'STRING_VALUE' => 'foo'], Enumeration\CompleteEnumeration::getConstants()); + $expected = [ + 'INTEGER_VALUE' => 1, + 'STRING_INTEGER_VALUE' => '2', + 'STRING_VALUE' => 'foo', + ]; + + $this->assertEquals($expected, Enumeration\CompleteEnumeration::getConstants()); } /** @@ -252,7 +153,14 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase */ public function getConstantsReturnsArrayOfPossibleValuesWithDefaultIfRequested() { - $this->assertEquals(['INTEGER_VALUE' => 1, 'STRING_VALUE' => 'foo', '__default' => 1], Enumeration\CompleteEnumeration::getConstants(true)); + $expected = [ + 'INTEGER_VALUE' => 1, + 'STRING_INTEGER_VALUE' => '2', + 'STRING_VALUE' => 'foo', + '__default' => 1, + ]; + + $this->assertEquals($expected, Enumeration\CompleteEnumeration::getConstants(true)); } /** @@ -261,7 +169,13 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase public function getConstantsCanBeCalledOnInstances() { $enumeration = new Enumeration\CompleteEnumeration(); - $this->assertEquals(['INTEGER_VALUE' => 1, 'STRING_VALUE' => 'foo'], $enumeration->getConstants()); + $expected = [ + 'INTEGER_VALUE' => 1, + 'STRING_INTEGER_VALUE' => '2', + 'STRING_VALUE' => 'foo', + ]; + + $this->assertEquals($expected, $enumeration->getConstants()); } /** @@ -307,12 +221,9 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase */ public function castCastsStringToEnumerationWithCorrespondingValue() { - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - ['1'] - ); - $this->assertSame(1, $enumeration->_get('value')); + $value = new Enumeration\CompleteEnumeration(Enumeration\CompleteEnumeration::STRING_VALUE); + + $this->assertSame((string)Enumeration\CompleteEnumeration::STRING_VALUE, (string)$value); } /** @@ -320,12 +231,9 @@ class EnumerationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase */ public function castCastsIntegerToEnumerationWithCorrespondingValue() { - $enumeration = $this->getAccessibleMock( - \TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration\CompleteEnumeration::class, - ['dummy'], - [1] - ); - $this->assertSame(1, $enumeration->_get('value')); + $value = new Enumeration\CompleteEnumeration(Enumeration\CompleteEnumeration::INTEGER_VALUE); + + $this->assertSame((int)(string)Enumeration\CompleteEnumeration::INTEGER_VALUE, (int)(string)$value); } /** diff --git a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/CompleteEnumeration.php b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/CompleteEnumeration.php index 60359870e3d672142bf0b1ce69809821e62ed108..01b894ceb14b90eee90fc520b4de8d1d59e07ba7 100644 --- a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/CompleteEnumeration.php +++ b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/CompleteEnumeration.php @@ -14,12 +14,15 @@ namespace TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This is an complete enumeration with all possible constant values */ -class CompleteEnumeration extends \TYPO3\CMS\Core\Type\Enumeration +final class CompleteEnumeration extends Enumeration { const __default = self::INTEGER_VALUE; const INTEGER_VALUE = 1; + const STRING_INTEGER_VALUE = '2'; const STRING_VALUE = 'foo'; } diff --git a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/DuplicateConstantValueEnumeration.php b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/DuplicateConstantValueEnumeration.php index 85e62ec7bcb5d0547bcad59a81b82b7fb2c8a3b5..de2b2f4c4868b8693750eee43b777a2cd4a3c855 100644 --- a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/DuplicateConstantValueEnumeration.php +++ b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/DuplicateConstantValueEnumeration.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This is an invalid enumeration because the constant values are not unique */ -class DuplicateConstantValueEnumeration extends \TYPO3\CMS\Core\Type\Enumeration +final class DuplicateConstantValueEnumeration extends Enumeration { const FOO = 1; const BAR = 1; diff --git a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/InvalidConstantEnumeration.php b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/InvalidConstantEnumeration.php index a0c7d3c250f624b19507491788787c7aaca1491b..01ee80a4f9f6fef56eac29e860a40469c87eb3fd 100644 --- a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/InvalidConstantEnumeration.php +++ b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/InvalidConstantEnumeration.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This is an invalid enumeration because an unsupported constant value is used */ -class InvalidConstantEnumeration extends \TYPO3\CMS\Core\Type\Enumeration +final class InvalidConstantEnumeration extends Enumeration { const FOO = 1.11; } diff --git a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingConstantsEnumeration.php b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingConstantsEnumeration.php index 356363b7857d9cdcded37bb412df9181e922e933..7eb2d12a89c447751af2e34b1192caa7cef1b85d 100644 --- a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingConstantsEnumeration.php +++ b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingConstantsEnumeration.php @@ -14,9 +14,11 @@ namespace TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This is an invalid enumeration because no constants are defined */ -class MissingConstantsEnumeration extends \TYPO3\CMS\Core\Type\Enumeration +final class MissingConstantsEnumeration extends Enumeration { } diff --git a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingDefaultEnumeration.php b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingDefaultEnumeration.php index bafbeda9693ff50c7dafc29b21eac6c62023fc5e..907a20c3d3e38c502f91efa24457dcbd9b5f9a1f 100644 --- a/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingDefaultEnumeration.php +++ b/typo3/sysext/core/Tests/Unit/Type/Fixture/Enumeration/MissingDefaultEnumeration.php @@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Tests\Unit\Type\Fixture\Enumeration; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Type\Enumeration; + /** * This is an enumeration without a default value so it must be called with a value */ -class MissingDefaultEnumeration extends \TYPO3\CMS\Core\Type\Enumeration +final class MissingDefaultEnumeration extends Enumeration { const FOO = 1; } diff --git a/typo3/sysext/indexed_search/Classes/Utility/LikeWildcard.php b/typo3/sysext/indexed_search/Classes/Utility/LikeWildcard.php index 867703c56bf10b96b254d6a50066a1db8c7b164a..973026e4073efcd559b4e09a687dc85c8f2f3854 100644 --- a/typo3/sysext/indexed_search/Classes/Utility/LikeWildcard.php +++ b/typo3/sysext/indexed_search/Classes/Utility/LikeWildcard.php @@ -14,12 +14,13 @@ namespace TYPO3\CMS\IndexedSearch\Utility; * The TYPO3 project - inspiring people to share! */ use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Type\Enumeration; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Enumeration object for LikeWildcard */ -class LikeWildcard extends \TYPO3\CMS\Core\Type\Enumeration +final class LikeWildcard extends Enumeration { const __default = self::BOTH;