[BUGFIX] DB field names exceed max length with 'zzz_deleted'
authorTolleiv Nietsch <info@tolleiv.de>
Sun, 20 May 2012 12:42:47 +0000 (14:42 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 20 May 2012 13:34:50 +0000 (15:34 +0200)
MySQL allows a maximum of 64 characters for column and table names.
When prefixing them with 'zzz_deleted' this limit might be reached
by accident. (e.g. with
'zzz_deleted_tx_powermail_tellAFriendForm_receiverEmailContentField')

The patch avoids the overstepping 64 characters.

At the same time the prefixed and shortened field names are more
likely to have the same name, therefore the names are cut
from the beginning.

Change-Id: I7e377e9fe26894b1c6e6b80b1b787e88b5df6087
Fixes: #33580
Releases: 4.5, 4.6, 4.7, 6.0
Reviewed-on: http://review.typo3.org/11330
Reviewed-by: Susanne Moog
Tested-by: Susanne Moog
Reviewed-by: Philipp Gampe
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
t3lib/class.t3lib_install.php

index 94011eb..f88b231 100644 (file)
@@ -87,6 +87,9 @@ class t3lib_install {
        var $multiplySize = 1; // Multiplier of SQL field size (for char, varchar and text fields)
        var $character_sets = array(); // Caching output of $GLOBALS['TYPO3_DB']->admin_get_charsets()
 
+               // Maximum field width of MYSQL
+       const MYSQL_MAXIMUM_FIELD_WIDTH = 64;
+
                // Internal, dynamic:
        var $setLocalconf = 0; // Used to indicate that a value is change in the line-array of localconf and that it should be written.
        var $messages = array(); // Used to set (error)messages from the executing functions like mail-sending, writing Localconf and such
@@ -793,6 +796,7 @@ class t3lib_install {
        function getUpdateSuggestions($diffArr, $keyList = 'extra,diff') {
                $statements = array();
                $deletedPrefixKey = $this->deletedPrefixKey;
+               $deletedPrefixLength = strlen($deletedPrefixKey);
                $remove = 0;
                if ($keyList == 'remove') {
                        $remove = 1;
@@ -822,8 +826,10 @@ class t3lib_install {
                                                                }
                                                                if ($theKey == 'extra') {
                                                                        if ($remove) {
-                                                                               if (substr($fN, 0, strlen($deletedPrefixKey)) != $deletedPrefixKey) {
-                                                                                       $statement = 'ALTER TABLE ' . $table . ' CHANGE ' . $fN . ' ' . $deletedPrefixKey . $fN . ' ' . $fV . ';';
+                                                                               if (substr($fN, 0, $deletedPrefixLength) !== $deletedPrefixKey) {
+                                                                                               // we've to make sure we don't exceed the maximal length
+                                                                                       $prefixedFieldName = $deletedPrefixKey . substr($fN, $deletedPrefixLength - self::MYSQL_MAXIMUM_FIELD_WIDTH);
+                                                                                       $statement = 'ALTER TABLE ' . $table . ' CHANGE ' . $fN . ' ' . $prefixedFieldName . ' ' . $fV . ';';
                                                                                        $statements['change'][md5($statement)] = $statement;
                                                                                } else {
                                                                                        $statement = 'ALTER TABLE ' . $table . ' DROP ' . $fN . ';';
@@ -900,7 +906,9 @@ class t3lib_install {
                                        if ($info['whole_table']) {
                                                if ($remove) {
                                                        if (substr($table, 0, strlen($deletedPrefixKey)) != $deletedPrefixKey) {
-                                                               $statement = 'ALTER TABLE ' . $table . ' RENAME ' . $deletedPrefixKey . $table . ';';
+                                                                       // we've to make sure we don't exceed the maximal length
+                                                               $prefixedTableName = $deletedPrefixKey . substr($table, $deletedPrefixLength - self::MYSQL_MAXIMUM_FIELD_WIDTH);
+                                                               $statement = 'ALTER TABLE ' . $table . ' RENAME ' . $prefixedTableName . ';';
                                                                $statements['change_table'][md5($statement)] = $statement;
                                                        } else {
                                                                $statement = 'DROP TABLE ' . $table . ';';