From 5e0fd86b6ea79960e39385610b070608e851c955 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?"J.=20Rene=CC=81e=20Beach"?= <splendidnoise@gmail.com>
Date: Thu, 6 Jun 2013 15:19:58 -0400
Subject: [PATCH] #1852454-112
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: J. Renée Beach <splendidnoise@gmail.com>
---
 core/includes/bootstrap.inc                        |    5 ++
 core/includes/theme.inc                            |    9 ++++
 core/includes/update.inc                           |   10 ++++
 .../Extension/ExtensionNameLengthException.php     |   13 +++++
 core/lib/Drupal/Core/Extension/ModuleHandler.php   |    7 +++
 core/modules/file/file.install                     |   18 ++++++-
 core/modules/menu_link/menu_link.install           |    2 +-
 core/modules/node/node.install                     |   17 +++++-
 .../Drupal/system/Tests/Module/ModuleEnable.php    |   16 ++++++
 .../ExistingModuleNameLengthUpgradePathTest.php    |   48 +++++++++++++++++
 .../Upgrade/ModuleNameLengthUpgradePathTest.php    |   57 ++++++++++++++++++++
 core/modules/system/system.install                 |   19 +++++++
 ...r_the_maximum_allowed_character_length.info.yml |    7 +++
 ...ver_the_maximum_allowed_character_length.module |    8 +++
 .../drupal-7.module_name_length.database.php       |   22 ++++++++
 core/modules/user/user.install                     |   44 +++++++++++++--
 16 files changed, 296 insertions(+), 6 deletions(-)
 create mode 100644 core/lib/Drupal/Core/Extension/ExtensionNameLengthException.php
 create mode 100644 core/modules/system/lib/Drupal/system/Tests/Upgrade/ExistingModuleNameLengthUpgradePathTest.php
 create mode 100644 core/modules/system/lib/Drupal/system/Tests/Upgrade/ModuleNameLengthUpgradePathTest.php
 create mode 100644 core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml
 create mode 100644 core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module
 create mode 100644 core/modules/system/tests/upgrade/drupal-7.module_name_length.database.php

diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index fa93dc8..c56a47b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -191,6 +191,11 @@
 const DRUPAL_KILOBYTE = 1024;
 
 /**
+ * The maximum number of characters in a module or theme name.
+ */
+const DRUPAL_EXTENSION_NAME_MAX_LENGTH = 50;
+
+/**
  * Time of the current request in seconds elapsed since the Unix Epoch.
  *
  * This differs from $_SERVER['REQUEST_TIME'], which is stored as a float
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index a3f967a..549d746 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -11,6 +11,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\Config;
 use Drupal\Core\Language\Language;
+use Drupal\Core\Extension\ExtensionNameLengthException;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Utility\ThemeRegistry;
 use Drupal\Core\Theme\ThemeSettings;
@@ -1497,6 +1498,14 @@ function theme_enable($theme_list) {
   $theme_config = config('system.theme');
   $disabled_themes = config('system.theme.disabled');
   foreach ($theme_list as $key) {
+    // Throw an exception if the theme name is too long.
+    if (strlen($key) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) {
+      throw new ExtensionNameLengthException(format_string('Theme name %name is over the maximum allowed length of @max characters.', array(
+        '%name' => $key,
+        '@max' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
+      )));
+    }
+
     // The value is not used; the weight is ignored for themes currently.
     $theme_config->set("enabled.$key", 0);
     $disabled_themes->clear($key);
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 9e6c91d..60124b3 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -359,6 +359,16 @@ function update_prepare_d8_bootstrap() {
       // Migrate each extension into configuration, varying by the extension's
       // status, and record its schema version.
       foreach ($result as $record) {
+        if (drupal_strlen($record->name) > 50) {
+          $requirements['module name too long ' . $record->name] = array(
+            'title' => 'Module name too long',
+            'value' => format_string('@name is @count characters long.', array('@name' => $record->name, '@count' => drupal_strlen($record->name))),
+            'description' => 'Module names longer than 50 characters are no longer supported.',
+            'severity' => REQUIREMENT_ERROR,
+          );
+          update_extra_requirements($requirements);
+        }
+
         if ($record->type == 'module') {
           if ($record->status && isset($module_data[$record->name])) {
             $module_config->set('enabled.' . $record->name, $record->weight);
diff --git a/core/lib/Drupal/Core/Extension/ExtensionNameLengthException.php b/core/lib/Drupal/Core/Extension/ExtensionNameLengthException.php
new file mode 100644
index 0000000..8930d1e
--- /dev/null
+++ b/core/lib/Drupal/Core/Extension/ExtensionNameLengthException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Extension\ExtensionNameLengthException.
+ */
+
+namespace Drupal\Core\Extension;
+
+/**
+ * Exception thrown when the extension's name length exceeds the allowed maximum.
+ */
+class ExtensionNameLengthException extends \Exception { }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 3a5ffbe..3353d87 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -546,6 +546,13 @@ public function enable($module_list, $enable_dependencies = TRUE) {
           unset($module_list[$module]);
           continue;
         }
+        // Throw an exception if the module name is too long.
+        if (strlen($module) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) {
+          throw new ExtensionNameLengthException(format_string('Module name %name is over the maximum allowed length of @max characters.', array(
+            '%name' => $module,
+            '@max' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
+          )));
+        }
         $module_list[$module] = $module_data[$module]->sort;
 
         // Add dependencies to the list, with a placeholder weight.
diff --git a/core/modules/file/file.install b/core/modules/file/file.install
index 7ce65bb..48f33de 100644
--- a/core/modules/file/file.install
+++ b/core/modules/file/file.install
@@ -112,7 +112,7 @@ function file_schema() {
       'module' => array(
         'description' => 'The name of the module that is using the file.',
         'type' => 'varchar',
-        'length' => 255,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -271,3 +271,19 @@ function file_update_8001() {
   );
   db_change_field('file_usage', 'id', 'id', $spec);
 }
+
+/**
+ * Convert the 'module' column in {file_usage} to the maximum shortname length.
+ */
+function file_update_8002() {
+  if (db_field_exists('file_usage', 'module')) {
+    $spec = array(
+      'description' => 'The name of the module that is using the file.',
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+      'default' => '',
+    );
+    db_change_field('file_usage', 'module', 'module', $spec);
+  }
+}
diff --git a/core/modules/menu_link/menu_link.install b/core/modules/menu_link/menu_link.install
index 1d80679..a09be43 100644
--- a/core/modules/menu_link/menu_link.install
+++ b/core/modules/menu_link/menu_link.install
@@ -75,7 +75,7 @@ function menu_link_schema() {
       'module' => array(
         'description' => 'The name of the module that generated this link.',
         'type' => 'varchar',
-        'length' => 255,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
         'default' => 'system',
       ),
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 2e761ae..60f3b5a 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -412,7 +412,7 @@ function node_schema() {
       'module' => array(
         'description' => 'The module defining this node type.',
         'type' => 'varchar',
-        'length' => 255,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
       ),
       'description' => array(
@@ -1147,6 +1147,21 @@ function node_update_8018() {
 }
 
 /**
+ * Convert the 'module' column in {node_type} to the maximum shortname length.
+ */
+function node_update_8019() {
+  if (db_field_exists('node_type', 'module')) {
+    $spec = array(
+      'description' => 'The module defining this node type.',
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+    );
+    db_change_field('node_type', 'module', 'module', $spec);
+  }
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x"
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleEnable.php b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleEnable.php
index b2d08fc..427f86f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleEnable.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleEnable.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Module;
 
+use Drupal\Core\Extension\ExtensionNameLengthException;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -44,4 +45,19 @@ function testRequiredModuleSchemaVersions() {
     $this->assertTrue($version > 0, 'User module version is > 0.');
   }
 
+  /**
+   * Tests that an exception is thrown when a module name is too long.
+   */
+  function testModuleNameLength() {
+    $module_name = 'invalid_module_name_over_the_maximum_allowed_character_length';
+    $message = format_string('Exception thrown when enabling module %name with a name length over the allowed maximum', array('%name' => $module_name));
+    try {
+      module_enable(array($module_name));
+      $this->fail($message);
+    }
+    catch (ExtensionNameLengthException $e) {
+      $this->pass($message);
+    }
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/ExistingModuleNameLengthUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/ExistingModuleNameLengthUpgradePathTest.php
new file mode 100644
index 0000000..d1004cc
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/ExistingModuleNameLengthUpgradePathTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Upgrade\ExistingModuleNameLengthUpgradePathTest.
+ */
+
+namespace Drupal\system\Tests\Upgrade;
+
+use Drupal\Core\Database\DatabaseExceptionWrapper;
+
+/**
+ * Performs upgrade path tests for module name length related changes.
+ */
+class ExistingModuleNameLengthUpgradePathTest extends UpgradePathTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name'  => 'Module name length upgrade test (existing module)',
+      'description'  => 'Upgrade path test when there is an installed module with a too long name.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz',
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.module_name_length.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Checks that upgrading is not possible when there is a too long module name.
+   */
+  public function testUpgradeAborts() {
+    // Load the first update screen.
+    $this->getUpdatePhp();
+    if (!$this->assertResponse(200)) {
+      throw new \Exception('Initial GET to update.php did not return HTTP 200 status.');
+    }
+
+    $this->assertText('Module name too long');
+    $this->assertNoFieldByXPath('//input[@type="submit"]', 'Allowed to continue with the update process.');
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/ModuleNameLengthUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/ModuleNameLengthUpgradePathTest.php
new file mode 100644
index 0000000..9525d6f
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/ModuleNameLengthUpgradePathTest.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Upgrade\ModuleNameLengthUpgradePathTest.
+ */
+
+namespace Drupal\system\Tests\Upgrade;
+
+use Drupal\Core\Database\DatabaseExceptionWrapper;
+
+/**
+ * Performs upgrade path tests for module name length related changes.
+ */
+class ModuleNameLengthUpgradePathTest extends UpgradePathTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name'  => 'Module name length upgrade test',
+      'description'  => 'Upgrade path tests for module name length related changes.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Performs upgrade path tests for module name length related changes.
+   */
+  public function testModuleNameLengths() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+    // Make sure that the module colums where shortened.
+    try {
+      db_insert('file_usage')
+        ->fields(array(
+          'fid' => 2,
+          'module' => str_repeat('b', 51),
+          'type' => $this->randomName(),
+          'id' => $this->randomName(),
+          'count' => 1,
+        ))
+        ->execute();
+      $this->fail('Length of {file_usage}.module successfully updated.');
+    }
+    catch (DatabaseExceptionWrapper $e) {
+      $this->pass('Length of {file_usage}.module successfully updated.');
+    }
+  }
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index f345d2c..939f3ef 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -2223,6 +2223,25 @@ function system_update_8057() {
 }
 
 /**
+ * Change the length of the 'module' column to the maximum length.
+ *
+ * @see system_update_8048()
+ */
+function system_update_8058() {
+  if (db_field_exists('menu_links', 'module')) {
+    $spec = array(
+      'description' => 'The name of the module that generated this link.',
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+      'default' => 'system',
+    );
+    db_change_field('menu_links', 'module', 'module', $spec);
+  }
+
+}
+
+/**
  * @} End of "defgroup updates-7.x-to-8.x".
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml
new file mode 100644
index 0000000..16d9c78
--- /dev/null
+++ b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.info.yml
@@ -0,0 +1,7 @@
+name: 'Module name length test'
+type: module
+description: 'Test module with a name over the maximum allowed characters.'
+package: Testing
+version: VERSION
+core: 8.x
+hidden: TRUE
diff --git a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module
new file mode 100644
index 0000000..d0dc049
--- /dev/null
+++ b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @file
+ * Module with a module name over the maximum allowed number of characters.
+ *
+ * @see DRUPAL_MODULE_NAME_MAX_LENGTH
+ */
diff --git a/core/modules/system/tests/upgrade/drupal-7.module_name_length.database.php b/core/modules/system/tests/upgrade/drupal-7.module_name_length.database.php
new file mode 100644
index 0000000..9c78219
--- /dev/null
+++ b/core/modules/system/tests/upgrade/drupal-7.module_name_length.database.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Database additions for role tests. Used in
+ * \Drupal\system\Tests\Upgrade\FilledStandardUpgradePathTest.
+ *
+ * This dump only contains data and schema components relevant for user data
+ * upgrade tests. The drupal-7.bare.minimal.database.php.gz file is imported before
+ * this dump, so the two form the database structure expected in tests
+ * altogether.
+ */
+
+db_insert('system')
+  ->fields(array(
+    'filename' => 'modules/invalid_module_name_over_the_maximum_allowed_character_length.module',
+    'name' => 'invalid_module_name_over_the_maximum_allowed_character_length',
+    'type' => 'module',
+    'status' => 1,
+    'schema_version' => 0,
+  ))
+  ->execute();
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index a8e9168..5600d03 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -60,7 +60,7 @@ function user_schema() {
       ),
       'theme' => array(
         'type' => 'varchar',
-        'length' => 255,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
         'description' => "User's default theme.",
@@ -167,7 +167,7 @@ function user_schema() {
       ),
       'module' => array(
         'type' => 'varchar',
-        'length' => 255,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
         'description' => "The module declaring the permission.",
@@ -198,7 +198,7 @@ function user_schema() {
       'module' => array(
         'description' => 'The name of the module declaring the variable.',
         'type' => 'varchar',
-        'length' => 204,
+        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -1059,5 +1059,43 @@ function user_update_8017() {
 }
 
 /**
+ * Use the maximum allowed module name length in module name database fields.
+ */
+function user_update_8018() {
+  if (db_field_exists('role_permission', 'module')) {
+    $spec = array(
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+      'default' => '',
+      'description' => 'The module declaring the permission.',
+    );
+    db_change_field('role_permission', 'module', 'module', $spec);
+  }
+
+  if (db_field_exists('users_data', 'module')) {
+    $spec = array(
+      'description' => 'The name of the module declaring the variable.',
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+      'default' => '',
+    );
+    db_change_field('users_data', 'module', 'module', $spec);
+  }
+
+  if (db_field_exists('users', 'theme')) {
+    $spec = array(
+      'type' => 'varchar',
+      'length' => 50,
+      'not null' => TRUE,
+      'default' => '',
+      'description' => "User's default theme.",
+    );
+    db_change_field('users', 'theme', 'theme', $spec);
+  }
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x".
  */
-- 
1.7.10.4

