Commit 270db4a5 authored by catch's avatar catch

Issue #1852454 by patrickd, xjm, YesCT, Berdir, amateescu, Pancho, djroshi,...

Issue #1852454 by patrickd, xjm, YesCT, Berdir, amateescu, Pancho, djroshi, dealancer, Wim Leers, jessebeach: Restrict module and theme name lengths to 50 characters.
parent 81ca4d60
......@@ -189,6 +189,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.
*
......
......@@ -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;
......@@ -1498,6 +1499,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);
......
......@@ -359,6 +359,18 @@ 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) {
// Before migrating any extension into configuration, make sure the
// extensions name length is not higher than the limit.
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 <a href="https://drupal.org/node/2014073">no longer supported</a>.',
'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);
......
<?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 { }
......@@ -567,6 +567,16 @@ public function enable($module_list, $enable_dependencies = TRUE) {
$module_list = array_keys($module_list);
}
foreach ($module_list as $module) {
// 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,
)));
}
}
// Required for module installation checks.
include_once DRUPAL_ROOT . '/core/includes/install.inc';
......
......@@ -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);
}
}
......@@ -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',
),
......
......@@ -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(
......@@ -1144,6 +1144,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.
......
......@@ -7,17 +7,18 @@
namespace Drupal\system\Tests\Module;
use Drupal\Core\Extension\ExtensionNameLengthException;
use Drupal\simpletest\WebTestBase;
/**
* Tests module_enable().
* Tests enabling modules.
*/
class ModuleEnable extends WebTestBase {
public static function getInfo() {
return array(
'name' => 'Module enable',
'description' => 'Tests module_enable().',
'description' => 'Tests enabling modules.',
'group' => 'Module',
);
}
......@@ -44,4 +45,29 @@ 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 {
$this->container->get('module_handler')->enable(array($module_name));
$this->fail($message);
}
catch (ExtensionNameLengthException $e) {
$this->pass($message);
}
// Since for the UI, the submit callback uses FALSE, test that too.
$message = format_string('Exception thrown when enabling as if via the UI the module %name with a name length over the allowed maximum', array('%name' => $module_name));
try {
$this->container->get('module_handler')->enable(array($module_name), FALSE);
$this->fail($message);
}
catch (ExtensionNameLengthException $e) {
$this->pass($message);
}
}
}
<?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"]', 'Not allowed to continue with the update process.');
}
}
<?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.');
}
}
}
......@@ -2225,6 +2225,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.
......
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
<?php
/**
* @file
* Module with a module name over the maximum allowed number of characters.
*
* @see DRUPAL_MODULE_NAME_MAX_LENGTH
*/
<?php
/**
* @file
* Database additions for \Drupal\system\Tests\Upgrade\ExistingModuleNameLengthUpgradePathTest.
*
* The drupal-7.bare.database.php 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();
......@@ -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' => '',
),
......@@ -1049,6 +1049,44 @@ 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".
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment