diff --git a/includes/common.inc b/includes/common.inc index 725b20b6865e40f1c4ca612fcfaffa43a9789d65..9be957332ffd7062ef10e7fc3656cd29b6039126 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -6777,6 +6777,27 @@ function archiver_get_info() { return $archiver_info; } +/** + * Returns a string of supported archive extensions. + * + * @return + * A space-separated string of extensions suitable for use by the file + * validation system. + */ +function archiver_get_extensions() { + $valid_extensions = array(); + foreach (archiver_get_info() as $archive) { + foreach ($archive['extensions'] as $extension) { + foreach (explode('.', $extension) as $part) { + if (!in_array($part, $valid_extensions)) { + $valid_extensions[] = $part; + } + } + } + } + return implode(' ', $valid_extensions); +} + /** * Create the appropriate archiver for the specified file. * diff --git a/modules/update/tests/aaa_update_test.tar.gz b/modules/update/tests/aaa_update_test.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..22c97191019b16e1392a29b988894bf870fdda25 --- /dev/null +++ b/modules/update/tests/aaa_update_test.tar.gz @@ -0,0 +1 @@ +%:LO0W'b}(*! +Pe[H$ҵ['5:ղ=D1 G<bĘ8e65U-J\|sSb#s7+f.a?'~qgyn.l s{;]?idc^͠ 5ɲWXʧ0|rͣs8U_?$ƈ7o/|o}.2 Vumw`ƥҵ*rsѺ(f Zh .b,vrNwlgl{b3 T!B!B!B!7>( \ No newline at end of file diff --git a/modules/update/update.manager.inc b/modules/update/update.manager.inc index 6cd48271e05555cddf18913bcbf0cda33e52bea4..667ccafc5d58ca8c1b8e60f21af1aa7e156cceb7 100644 --- a/modules/update/update.manager.inc +++ b/modules/update/update.manager.inc @@ -457,17 +457,9 @@ function update_manager_update_ready_form_submit($form, &$form_state) { function update_manager_install_form($form, &$form_state, $context) { $form = array(); - // Collect all the supported archive file extensions for the UI text. - $extensions = array(); - $archiver_info = archiver_get_info(); - foreach ($archiver_info as $info) { - if (!empty($info['extensions'])) { - $extensions += $info['extensions']; - } - } $form['help_text'] = array( '#prefix' => '

', - '#markup' => t('To install a new module or theme, either enter the URL of an archive file you wish to install, or upload the archive file that you have downloaded. You can find modules and themes at http://drupal.org. The following archive extensions are supported: %extensions', array('@module_url' => 'http://drupal.org/project/modules', '@theme_url' => 'http://drupal.org/project/themes', '@drupal_org_url' => 'http://drupal.org', '%extensions' => implode(', ', $extensions))), + '#markup' => t('To install a new module or theme, either enter the URL of an archive file you wish to install, or upload the archive file that you have downloaded. You can find modules and themes at http://drupal.org.
The following archive extensions are supported: %extensions.', array('@module_url' => 'http://drupal.org/project/modules', '@theme_url' => 'http://drupal.org/project/themes', '@drupal_org_url' => 'http://drupal.org', '%extensions' => archiver_get_extensions())), '#suffix' => '

', ); @@ -538,10 +530,13 @@ function update_manager_install_form_submit($form, &$form_state) { } } elseif ($_FILES['files']['name']['project_upload']) { + $validators = array('file_validate_extensions' => array(archiver_get_extensions())); $field = 'project_upload'; - // @todo: add some validators here. - $finfo = file_save_upload($field, array(), NULL, FILE_EXISTS_REPLACE); - // @todo: find out if the module is already instealled, if so, throw an error. + if (!($finfo = file_save_upload($field, $validators, NULL, FILE_EXISTS_REPLACE))) { + // Failed to upload the file. file_save_upload() calls form_set_error() on + // failure. + return; + } $local_cache = $finfo->uri; } diff --git a/modules/update/update.test b/modules/update/update.test index 83f76d93f118646df87fe199aee143b9c4a96f45..66f7907fe8ddc3e1a297e9e95782025f86dd3153 100644 --- a/modules/update/update.test +++ b/modules/update/update.test @@ -493,3 +493,44 @@ class UpdateTestContribCase extends UpdateTestHelper { } +class UpdateTestUploadCase extends UpdateTestHelper { + public static function getInfo() { + return array( + 'name' => 'Upload and extract module functionality', + 'description' => 'Tests the update module\'s upload and extraction functionality.', + 'group' => 'Update', + ); + } + + public function setUp() { + parent::setUp('update'); + variable_set('allow_authorize_operations', TRUE); + $admin_user = $this->drupalCreateUser(array('administer software updates', 'administer site configuration')); + $this->drupalLogin($admin_user); + } + + /** + * Tests upload and extraction of a module. + */ + public function testUploadModule() { + // Images are not valid archives, so get one and try to install it. + $invalidArchiveFile = reset($this->drupalGetTestFiles('image')); + $edit = array( + 'files[project_upload]' => $invalidArchiveFile->uri, + ); + // This also checks that the correct archive extensions are allowed. + $this->drupalPost('admin/modules/install', $edit, t('Install')); + $this->assertText(t('Only files with the following extensions are allowed: @archive_extensions.', array('@archive_extensions' => archiver_get_extensions())),'Only valid archives can be uploaded.'); + + // Check to ensure an existing module can't be reinstalled. Also checks that + // the archive was extracted since we can't know if the module is already + // installed until after extraction. + $validArchiveFile = drupal_get_path('module', 'update') . '/tests/aaa_update_test.tar.gz'; + $edit = array( + 'files[project_upload]' => $validArchiveFile, + ); + $this->drupalPost('admin/modules/install', $edit, t('Install')); + $this->assertText(t('@module_name is already installed.', array('@module_name' => 'AAA Update test')), 'Existing module was extracted and not reinstalled.'); + } +} +