From 8d8a60b61546466d9ee6b2e7a3c914b4bd869a4b Mon Sep 17 00:00:00 2001 From: Bachir Soussi Chiadmi Date: Mon, 25 Sep 2017 15:16:35 +0200 Subject: [PATCH] security upadtes --- CHANGELOG.txt | 20 + includes/bootstrap.inc | 9 +- includes/common.inc | 2 +- includes/database/pgsql/database.inc | 12 +- includes/database/pgsql/install.inc | 2 +- includes/database/pgsql/select.inc | 4 +- includes/database/query.inc | 6 +- includes/database/schema.inc | 5 +- includes/database/sqlite/query.inc | 13 +- includes/database/sqlite/schema.inc | 2 +- includes/errors.inc | 6 +- includes/file.inc | 29 +- misc/drupal.js | 85 +++- modules/aggregator/aggregator.info | 6 +- modules/aggregator/aggregator.module | 8 + modules/aggregator/aggregator.test | 38 +- modules/aggregator/tests/aggregator_test.info | 6 +- modules/block/block.info | 6 +- modules/block/block.module | 19 +- modules/block/tests/block_test.info | 6 +- .../block_test_theme/block_test_theme.info | 6 +- modules/blog/blog.info | 6 +- modules/book/book.info | 6 +- modules/color/color.info | 6 +- modules/comment/comment.info | 6 +- modules/contact/contact.info | 6 +- modules/contact/contact.module | 9 +- modules/contact/contact.test | 22 + modules/contextual/contextual.info | 6 +- modules/dashboard/dashboard.info | 6 +- modules/dblog/dblog.info | 6 +- modules/field/field.info | 6 +- .../field_sql_storage/field_sql_storage.info | 6 +- modules/field/modules/list/list.info | 6 +- .../field/modules/list/tests/list_test.info | 6 +- modules/field/modules/number/number.info | 6 +- modules/field/modules/options/options.info | 6 +- modules/field/modules/text/text.info | 6 +- modules/field/tests/field_test.info | 6 +- modules/field/theme/field.tpl.php | 8 +- modules/field_ui/field_ui.info | 6 +- modules/file/file.info | 6 +- modules/file/file.module | 7 +- modules/file/tests/file.test | 74 +++ modules/file/tests/file_module_test.info | 6 +- modules/filter/filter.info | 6 +- modules/forum/forum.info | 6 +- modules/help/help.info | 6 +- modules/image/image.info | 6 +- modules/image/tests/image_module_test.info | 6 +- modules/locale/locale.info | 6 +- modules/locale/locale.test | 6 +- modules/locale/tests/locale_test.info | 6 +- modules/menu/menu.info | 6 +- modules/node/node.info | 6 +- modules/node/tests/node_access_test.info | 6 +- modules/node/tests/node_test.info | 6 +- modules/node/tests/node_test_exception.info | 6 +- modules/openid/openid.info | 6 +- modules/openid/tests/openid_test.info | 6 +- modules/overlay/overlay.info | 6 +- modules/path/path.info | 6 +- modules/php/php.info | 6 +- modules/poll/poll.info | 6 +- modules/profile/profile.info | 6 +- modules/rdf/rdf.info | 6 +- modules/rdf/tests/rdf_test.info | 6 +- modules/search/search.info | 6 +- .../search/tests/search_embedded_form.info | 6 +- modules/search/tests/search_extra_type.info | 6 +- modules/search/tests/search_node_tags.info | 6 +- modules/shortcut/shortcut.info | 6 +- modules/simpletest/drupal_web_test_case.php | 32 +- modules/simpletest/simpletest.info | 6 +- .../simpletest/tests/actions_loop_test.info | 6 +- modules/simpletest/tests/ajax_forms_test.info | 6 +- modules/simpletest/tests/ajax_test.info | 6 +- modules/simpletest/tests/batch_test.info | 6 +- modules/simpletest/tests/boot_test_1.info | 6 +- modules/simpletest/tests/boot_test_2.info | 6 +- modules/simpletest/tests/common.test | 2 +- modules/simpletest/tests/common_test.info | 6 +- .../tests/common_test_cron_helper.info | 6 +- modules/simpletest/tests/database_test.info | 6 +- .../drupal_autoload_test.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- .../simpletest/tests/entity_cache_test.info | 6 +- .../tests/entity_cache_test_dependency.info | 6 +- .../tests/entity_crud_hook_test.info | 6 +- .../tests/entity_query_access_test.info | 6 +- modules/simpletest/tests/error_test.info | 6 +- modules/simpletest/tests/file_test.info | 6 +- modules/simpletest/tests/filter_test.info | 6 +- modules/simpletest/tests/form_test.info | 6 +- modules/simpletest/tests/image_test.info | 6 +- modules/simpletest/tests/menu_test.info | 6 +- modules/simpletest/tests/module_test.info | 6 +- modules/simpletest/tests/path_test.info | 6 +- .../tests/psr_0_test/psr_0_test.info | 6 +- .../tests/psr_4_test/psr_4_test.info | 6 +- .../simpletest/tests/requirements1_test.info | 6 +- .../simpletest/tests/requirements2_test.info | 6 +- modules/simpletest/tests/session_test.info | 6 +- .../tests/system_dependencies_test.info | 6 +- ...atible_core_version_dependencies_test.info | 6 +- ...system_incompatible_core_version_test.info | 6 +- ...ible_module_version_dependencies_test.info | 6 +- ...stem_incompatible_module_version_test.info | 6 +- .../tests/system_project_namespace_test.info | 6 +- modules/simpletest/tests/system_test.info | 6 +- modules/simpletest/tests/taxonomy_test.info | 6 +- modules/simpletest/tests/theme_test.info | 6 +- .../themes/test_basetheme/test_basetheme.info | 6 +- .../themes/test_subtheme/test_subtheme.info | 6 +- .../tests/themes/test_theme/test_theme.info | 6 +- .../test_theme_nyan_cat.info | 6 +- .../simpletest/tests/update_script_test.info | 6 +- modules/simpletest/tests/update_test_1.info | 6 +- modules/simpletest/tests/update_test_2.info | 6 +- modules/simpletest/tests/update_test_3.info | 6 +- modules/simpletest/tests/url_alter_test.info | 6 +- modules/simpletest/tests/xmlrpc_test.info | 6 +- modules/statistics/statistics.info | 6 +- modules/statistics/statistics.module | 2 +- modules/syslog/syslog.info | 6 +- modules/system/system.info | 6 +- modules/system/system.install | 2 +- modules/system/tests/cron_queue_test.info | 6 +- modules/system/tests/system_cron_test.info | 6 +- modules/taxonomy/taxonomy.info | 6 +- modules/toolbar/toolbar.info | 6 +- modules/tracker/tracker.info | 6 +- .../translation/tests/translation_test.info | 6 +- modules/translation/translation.info | 6 +- modules/trigger/tests/trigger_test.info | 6 +- modules/trigger/trigger.info | 6 +- modules/update/tests/aaa_update_test.info | 6 +- modules/update/tests/bbb_update_test.info | 6 +- modules/update/tests/ccc_update_test.info | 6 +- .../update_test_admintheme.info | 6 +- .../update_test_basetheme.info | 6 +- .../update_test_subtheme.info | 6 +- modules/update/tests/update_test.info | 6 +- modules/update/update.info | 6 +- modules/user/tests/user_form_test.info | 6 +- modules/user/user.info | 6 +- modules/user/user.module | 9 +- modules/user/user.test | 76 ++- profiles/minimal/minimal.info | 6 +- profiles/standard/standard.info | 6 +- ...drupal_system_listing_compatible_test.info | 6 +- ...upal_system_listing_incompatible_test.info | 6 +- profiles/testing/testing.info | 6 +- sites/all/modules/README.txt | 4 - sites/all/modules/references/CHANGELOG.txt | 19 +- .../node_reference/node_reference.info | 6 +- .../node_reference/node_reference.install | 38 ++ .../node_reference/node_reference.module | 194 +++++--- .../node_reference/node_reference.test | 55 +++ .../modules/references/references.feeds.inc | 2 +- sites/all/modules/references/references.info | 6 +- .../all/modules/references/references.module | 2 +- .../references_uuid/references_uuid.info | 12 + .../references_uuid/references_uuid.module | 33 ++ .../user_reference/user_reference.info | 6 +- .../user_reference/user_reference.install | 29 ++ .../user_reference/user_reference.module | 51 +- sites/all/modules/smtp/CHANGELOG.txt | 60 --- sites/all/modules/smtp/README.txt | 20 +- sites/all/modules/smtp/smtp.admin.inc | 215 +++++--- sites/all/modules/smtp/smtp.info | 14 +- sites/all/modules/smtp/smtp.install | 112 ++++- sites/all/modules/smtp/smtp.mail.inc | 458 +++++++++++++----- sites/all/modules/smtp/smtp.module | 112 ++++- sites/all/modules/smtp/smtp.phpmailer.inc | 166 ++++--- sites/all/modules/smtp/smtp.transport.inc | 64 +-- sites/all/modules/smtp/smtp.variable.inc | 40 ++ sites/all/modules/smtp/tests/smtp.unit.test | 200 ++++++++ sites/all/modules/smtp/tests/smtp_tests.info | 12 + .../all/modules/smtp/tests/smtp_tests.module | 16 + sites/all/modules/views/README.txt | 53 +- .../all/modules/views/css/views-admin-rtl.css | 2 +- .../handlers/views_handler_area_result.inc | 1 - .../views/handlers/views_handler_filter.inc | 14 +- .../modules/views/help/api-handler-area.html | 1 + sites/all/modules/views/includes/admin.inc | 2 +- sites/all/modules/views/includes/ajax.inc | 11 +- sites/all/modules/views/includes/handlers.inc | 144 +++--- sites/all/modules/views/includes/view.inc | 38 +- sites/all/modules/views/js/ajax_view.js | 4 + sites/all/modules/views/js/base.js | 7 +- .../modules/views/modules/comment.views.inc | 65 ++- .../all/modules/views/modules/node.views.inc | 2 +- .../views_handler_argument_dates_various.inc | 20 +- .../node/views_plugin_row_node_view.inc | 3 +- .../modules/views/modules/search.views.inc | 4 +- .../search/views_handler_argument_search.inc | 2 +- .../search/views_handler_filter_search.inc | 2 +- .../modules/views/modules/taxonomy.views.inc | 2 +- .../views_handler_argument_term_node_tid.inc | 1 + .../taxonomy/views_handler_field_taxonomy.inc | 9 + .../views_handler_field_term_node_tid.inc | 2 +- .../views_handler_filter_term_node_tid.inc | 6 +- ...ws_handler_relationship_node_term_data.inc | 2 +- ...plugin_argument_validate_taxonomy_term.inc | 5 +- .../user/views_handler_field_user_name.inc | 2 +- .../user/views_plugin_row_user_view.inc | 2 +- .../all/modules/views/modules/views.views.inc | 2 +- .../views/plugins/views_plugin_cache.inc | 10 +- .../views/plugins/views_plugin_cache_time.inc | 4 +- .../views/plugins/views_plugin_display.inc | 63 ++- .../plugins/views_plugin_display_block.inc | 3 +- .../plugins/views_plugin_display_page.inc | 14 +- .../views/plugins/views_plugin_pager_full.inc | 2 +- .../views/plugins/views_plugin_query.inc | 3 + .../plugins/views_plugin_query_default.inc | 5 +- .../views/plugins/views_plugin_style.inc | 5 +- .../plugins/views_plugin_style_jump_menu.inc | 2 +- .../plugins/views_plugin_style_mapping.inc | 3 +- .../tests/styles/views_plugin_style.test | 6 +- sites/all/modules/views/tests/views_ajax.test | 109 +++++ .../views/tests/views_exposed_form.test | 32 ++ sites/all/modules/views/tests/views_test.info | 6 +- .../views/tests/views_test.views_default.inc | 108 +++++ sites/all/modules/views/tests/views_view.test | 7 + sites/all/modules/views/theme/theme.inc | 6 +- .../modules/views/theme/views-more.tpl.php | 5 +- .../views/theme/views-ui-edit-item.tpl.php | 45 -- sites/all/modules/views/views.api.php | 2 +- sites/all/modules/views/views.info | 8 +- sites/all/modules/views/views.install | 24 +- sites/all/modules/views/views.module | 28 +- sites/all/modules/views/views.tokens.inc | 1 - sites/all/modules/views/views_ui.info | 7 +- sites/all/modules/views/views_ui.module | 171 +++++-- themes/bartik/bartik.info | 6 +- themes/garland/garland.info | 6 +- themes/seven/seven.info | 6 +- themes/stark/stark.info | 6 +- 240 files changed, 3022 insertions(+), 1300 deletions(-) delete mode 100644 sites/all/modules/README.txt create mode 100644 sites/all/modules/references/node_reference/node_reference.install create mode 100644 sites/all/modules/references/references_uuid/references_uuid.info create mode 100644 sites/all/modules/references/references_uuid/references_uuid.module create mode 100644 sites/all/modules/references/user_reference/user_reference.install delete mode 100644 sites/all/modules/smtp/CHANGELOG.txt create mode 100644 sites/all/modules/smtp/smtp.variable.inc create mode 100644 sites/all/modules/smtp/tests/smtp.unit.test create mode 100644 sites/all/modules/smtp/tests/smtp_tests.info create mode 100644 sites/all/modules/smtp/tests/smtp_tests.module create mode 100644 sites/all/modules/views/tests/views_ajax.test delete mode 100644 sites/all/modules/views/theme/views-ui-edit-item.tpl.php diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c015fb4..5ebbf21 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,24 @@ +Drupal 7.56, 2017-06-21 +----------------------- +- Fixed security issues (access bypass). See SA-CORE-2017-003. + +Drupal 7.55, 2017-06-07 +----------------------- +- Fixed incompatibility with PHP versions 7.0.19 and 7.1.5 due to duplicate + DATE_RFC7231 definition. +- Made Drupal core pass all automated tests on PHP 7.1. +- Allowed services such as Let's Encrypt to work with Drupal on Apache, by + making Drupal's .htaccess file allow access to the .well-known directory + defined by RFC 5785. +- Made new Drupal sites work correctly on Apache 2.4 when the mod_access_compat + Apache module is disabled. +- Fixed Drupal's URL-generating functions to always encode '[' and ']' so that + the URLs will pass HTML5 validation. +- Various additional bug fixes. +- Various API documentation improvements. +- Additional automated test coverage. + Drupal 7.54, 2017-02-01 ----------------------- - Modules are now able to define theme engines (API addition: diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 99a5ac8..c06055e 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.54'); +define('VERSION', '7.56'); /** * Core API compatibility. @@ -254,8 +254,13 @@ define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' * http://tools.ietf.org/html/rfc7231#section-7.1.1.1 * * Example: Sun, 06 Nov 1994 08:49:37 GMT + * + * This constant was introduced in PHP 7.0.19 and PHP 7.1.5 but needs to be + * defined by Drupal for earlier PHP versions. */ -define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T'); +if (!defined('DATE_RFC7231')) { + define('DATE_RFC7231', 'D, d M Y H:i:s \G\M\T'); +} /** * Provides a caching wrapper to be used in place of large array structures. diff --git a/includes/common.inc b/includes/common.inc index da8996a..a32930a 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') { $params = array(); foreach ($query as $key => $value) { - $key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key)); + $key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key); // Recurse into children. if (is_array($value)) { diff --git a/includes/database/pgsql/database.inc b/includes/database/pgsql/database.inc index 4157965..fb3d0ab 100644 --- a/includes/database/pgsql/database.inc +++ b/includes/database/pgsql/database.inc @@ -11,7 +11,7 @@ */ /** - * The name by which to obtain a lock for retrive the next insert id. + * The name by which to obtain a lock for retrieving the next insert id. */ define('POSTGRESQL_NEXTID_LOCK', 1000); @@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { $connection_options['pdo'] += array( // Prepared statements are most effective for performance when queries // are recycled (used several times). However, if they are not re-used, - // prepared statements become ineffecient. Since most of Drupal's + // prepared statements become inefficient. Since most of Drupal's // prepared queries are not re-used, it should be faster to emulate // the preparation than to actually ready statements for re-use. If in // doubt, reset to FALSE and measure performance. @@ -175,14 +175,14 @@ class DatabaseConnection_pgsql extends DatabaseConnection { } /** - * Retrive a the next id in a sequence. + * Retrieve the next id in a sequence. * * PostgreSQL has built in sequences. We'll use these instead of inserting * and updating a sequences table. */ public function nextId($existing = 0) { - // Retrive the name of the sequence. This information cannot be cached + // Retrieve the name of the sequence. This information cannot be cached // because the prefix may change, for example, like it does in simpletests. $sequence_name = $this->makeSequenceName('sequences', 'value'); @@ -194,7 +194,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { } // PostgreSQL advisory locks are simply locks to be used by an - // application such as Drupal. This will prevent other Drupal proccesses + // application such as Drupal. This will prevent other Drupal processes // from altering the sequence while we are. $this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")"); @@ -209,7 +209,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection { // Reset the sequence to a higher value than the existing id. $this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1)); - // Retrive the next id. We know this will be as high as we want it. + // Retrieve the next id. We know this will be as high as we want it. $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField(); $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")"); diff --git a/includes/database/pgsql/install.inc b/includes/database/pgsql/install.inc index c77f4ea..122031e 100644 --- a/includes/database/pgsql/install.inc +++ b/includes/database/pgsql/install.inc @@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks { LANGUAGE \'sql\'' ); - // Using || to concatenate in Drupal is not recommeneded because there are + // Using || to concatenate in Drupal is not recommended because there are // database drivers for Drupal that do not support the syntax, however // they do support CONCAT(item1, item2) which we can replicate in // PostgreSQL. PostgreSQL requires the function to be defined for each diff --git a/includes/database/pgsql/select.inc b/includes/database/pgsql/select.inc index f6a83db..5b8736d 100644 --- a/includes/database/pgsql/select.inc +++ b/includes/database/pgsql/select.inc @@ -80,7 +80,7 @@ class SelectQuery_pgsql extends SelectQuery { } // If a table loads all fields, it can not be added again. It would - // result in an ambigious alias error because that field would be loaded + // result in an ambiguous alias error because that field would be loaded // twice: Once through table_alias.* and once directly. If the field // actually belongs to a different table, it must be added manually. foreach ($this->tables as $table) { @@ -90,7 +90,7 @@ class SelectQuery_pgsql extends SelectQuery { } // If $field contains an characters which are not allowed in a field name - // it is considered an expression, these can't be handeld automatically + // it is considered an expression, these can't be handled automatically // either. if ($this->connection->escapeField($field) != $field) { return $return; diff --git a/includes/database/query.inc b/includes/database/query.inc index c9c5a83..048c8a2 100644 --- a/includes/database/query.inc +++ b/includes/database/query.inc @@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface { /** * Executes the DELETE query. * - * @return - * The return value is dependent on the database connection. + * @return int + * The number of rows affected by the delete query. */ public function execute() { $values = array(); @@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface { * MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called * instead. MergeQuery::fields() can also be called which calls both of these * methods as the common case is to use the same column-value pairs for both - * INSERT and UPDATE. However, this is not mandatory. Another convinient + * INSERT and UPDATE. However, this is not mandatory. Another convenient * wrapper is MergeQuery::key() which adds the same column-value pairs to the * condition and the INSERT query part. * diff --git a/includes/database/schema.inc b/includes/database/schema.inc index d8344c6..31862db 100644 --- a/includes/database/schema.inc +++ b/includes/database/schema.inc @@ -164,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc'; * @see drupal_install_schema() */ +/** + * Base class for database schema definitions. + */ abstract class DatabaseSchema implements QueryPlaceholderInterface { protected $connection; @@ -291,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface { protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) { $info = $this->connection->getConnectionOptions(); - // Retrive the table name and schema + // Retrieve the table name and schema $table_info = $this->getPrefixInfo($table_name, $add_prefix); $condition = new DatabaseCondition('AND'); diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc index 1c6289b..c9c028b 100644 --- a/includes/database/sqlite/query.inc +++ b/includes/database/sqlite/query.inc @@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery { /** * SQLite specific implementation of DeleteQuery. - * - * When the WHERE is omitted from a DELETE statement and the table being deleted - * has no triggers, SQLite uses an optimization to erase the entire table content - * without having to visit each row of the table individually. - * - * Prior to SQLite 3.6.5, SQLite does not return the actual number of rows deleted - * by that optimized "truncate" optimization. */ class DeleteQuery_sqlite extends DeleteQuery { public function execute() { + // When the WHERE is omitted from a DELETE statement and the table being + // deleted has no triggers, SQLite uses an optimization to erase the entire + // table content without having to visit each row of the table individually. + // Prior to SQLite 3.6.5, SQLite does not return the actual number of rows + // deleted by that optimized "truncate" optimization. But we want to return + // the number of rows affected, so we calculate it directly. if (!count($this->condition)) { $total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField(); parent::execute(); diff --git a/includes/database/sqlite/schema.inc b/includes/database/sqlite/schema.inc index df19d2f..281d8fc 100644 --- a/includes/database/sqlite/schema.inc +++ b/includes/database/sqlite/schema.inc @@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema { // database. So the syntax '...RENAME TO database.table' would fail. // So we must determine the full table name here rather than surrounding // the table with curly braces incase the db_prefix contains a reference - // to a database outside of our existsing database. + // to a database outside of our existing database. $info = $this->getPrefixInfo($new_name); $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']); diff --git a/includes/errors.inc b/includes/errors.inc index 7393148..3548d1f 100644 --- a/includes/errors.inc +++ b/includes/errors.inc @@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c _drupal_log_error(array( '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error', // The standard PHP error handler considers that the error messages - // are HTML. We mimick this behavior here. + // are HTML. We mimic this behavior here. '!message' => filter_xss_admin($message), '%function' => $caller['function'], '%file' => $caller['file'], @@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) { return array( '%type' => get_class($exception), // The standard PHP exception handler considers that the exception message - // is plain-text. We mimick this behavior here. + // is plain-text. We mimic this behavior here. '!message' => check_plain($message), '%function' => $caller['function'], '%file' => $caller['file'], @@ -233,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) { } else { // Display the message if the current error reporting level allows this type - // of message to be displayed, and unconditionnaly in update.php. + // of message to be displayed, and unconditionally in update.php. if (error_displayable($error)) { $class = 'error'; diff --git a/includes/file.inc b/includes/file.inc index de9d17d..fa7f5eb 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -535,7 +535,18 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006 EOF; if ($private) { - $lines = "Deny from all\n\n" . $lines; + $lines = << + Require all denied + + +# Deny all requests from Apache 2.0-2.2. + + Deny from all + +EOF + . "\n\n" . $lines; } return $lines; @@ -889,7 +900,6 @@ function file_valid_uri($uri) { */ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) { $original_source = $source; - $original_destination = $destination; // Assert that the source file actually exists. if (!file_exists($source)) { @@ -1604,6 +1614,20 @@ function file_save_upload($form_field_name, $validators = array(), $destination // If we made it this far it's safe to record this file in the database. if ($file = file_save($file)) { + // Track non-public files in the session if they were uploaded by an + // anonymous user. This allows modules such as the File module to only + // grant view access to the specific anonymous user who uploaded the file. + // See file_file_download(). + // The 'file_public_schema' variable is used to allow other publicly + // accessible file schemes to be treated the same as the public:// scheme + // provided by Drupal core and to avoid adding unnecessary data to the + // session (and the resulting bypass of the page cache) in those cases. For + // security reasons, only schemes that are completely publicly accessible, + // with no download restrictions, should be added to this variable. See + // file_managed_file_value(). + if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) { + $_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid; + } // Add file to the cache. $upload_cache[$form_field_name] = $file; return $file; @@ -2553,7 +2577,6 @@ function file_directory_temp() { * An associative array of headers, as expected by file_transfer(). */ function file_get_content_headers($file) { - $name = mime_header_encode($file->filename); $type = mime_header_encode($file->filemime); return array( diff --git a/misc/drupal.js b/misc/drupal.js index 03eef50..d86ea1f 100644 --- a/misc/drupal.js +++ b/misc/drupal.js @@ -168,23 +168,76 @@ Drupal.checkPlain = function (str) { Drupal.formatString = function(str, args) { // Transform arguments before inserting them. for (var key in args) { - switch (key.charAt(0)) { - // Escaped only. - case '@': - args[key] = Drupal.checkPlain(args[key]); - break; - // Pass-through. - case '!': - break; - // Escaped and placeholder. - case '%': - default: - args[key] = Drupal.theme('placeholder', args[key]); - break; + if (args.hasOwnProperty(key)) { + switch (key.charAt(0)) { + // Escaped only. + case '@': + args[key] = Drupal.checkPlain(args[key]); + break; + // Pass-through. + case '!': + break; + // Escaped and placeholder. + default: + args[key] = Drupal.theme('placeholder', args[key]); + break; + } } - str = str.replace(key, args[key]); } - return str; + + return Drupal.stringReplace(str, args, null); +}; + +/** + * Replace substring. + * + * The longest keys will be tried first. Once a substring has been replaced, + * its new value will not be searched again. + * + * @param {String} str + * A string with placeholders. + * @param {Object} args + * Key-value pairs. + * @param {Array|null} keys + * Array of keys from the "args". Internal use only. + * + * @return {String} + * Returns the replaced string. + */ +Drupal.stringReplace = function (str, args, keys) { + if (str.length === 0) { + return str; + } + + // If the array of keys is not passed then collect the keys from the args. + if (!$.isArray(keys)) { + keys = []; + for (var k in args) { + if (args.hasOwnProperty(k)) { + keys.push(k); + } + } + + // Order the keys by the character length. The shortest one is the first. + keys.sort(function (a, b) { return a.length - b.length; }); + } + + if (keys.length === 0) { + return str; + } + + // Take next longest one from the end. + var key = keys.pop(); + var fragments = str.split(key); + + if (keys.length) { + for (var i = 0; i < fragments.length; i++) { + // Process each fragment with a copy of remaining keys. + fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0)); + } + } + + return fragments.join(args[key]); }; /** @@ -251,7 +304,7 @@ Drupal.t = function (str, args, options) { * A translated string. */ Drupal.formatPlural = function (count, singular, plural, args, options) { - var args = args || {}; + args = args || {}; args['@count'] = count; // Determine the index of the plural form. var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1); diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info index 67ebdc0..09caa00 100644 --- a/modules/aggregator/aggregator.info +++ b/modules/aggregator/aggregator.info @@ -7,8 +7,8 @@ files[] = aggregator.test configure = admin/config/services/aggregator/settings stylesheets[all][] = aggregator.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module index 70f8c5c..02c9ec4 100644 --- a/modules/aggregator/aggregator.module +++ b/modules/aggregator/aggregator.module @@ -455,6 +455,14 @@ function aggregator_save_category($edit) { db_delete('aggregator_category') ->condition('cid', $edit['cid']) ->execute(); + // Remove category from feeds. + db_delete('aggregator_category_feed') + ->condition('cid', $edit['cid']) + ->execute(); + // Remove category from feed items. + db_delete('aggregator_category_item') + ->condition('cid', $edit['cid']) + ->execute(); // Make sure there is no active block for this category. if (module_exists('block')) { db_delete('block') diff --git a/modules/aggregator/aggregator.test b/modules/aggregator/aggregator.test index d84ee78..afa791d 100644 --- a/modules/aggregator/aggregator.test +++ b/modules/aggregator/aggregator.test @@ -418,7 +418,7 @@ class CategorizeFeedTestCase extends AggregatorTestCase { } /** - * Creates a feed and makes sure you can add more than one category to it. + * Creates a feed and makes sure you can add/delete categories to it. */ function testCategorizeFeed() { @@ -448,7 +448,31 @@ class CategorizeFeedTestCase extends AggregatorTestCase { // Assert the feed has two categories. $this->getFeedCategories($db_feed); $this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories'); + + // Use aggregator_save_feed() to delete a category. + $category = reset($categories); + aggregator_save_category(array('cid' => $category->cid)); + + // Assert that category is deleted. + $db_category = db_query("SELECT COUNT(*) FROM {aggregator_category} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField(); + $this->assertFalse($db_category, format_string('The category %title has been deleted.', array('%title' => $category->title))); + + // Assert that category has been removed from feed. + $categorized_feeds = db_query("SELECT COUNT(*) FROM {aggregator_category_feed} WHERE cid = :cid", array(':cid' => $category->cid))->fetchField(); + $this->assertFalse($categorized_feeds, format_string('The category %title has been removed from feed %feed_title.', array('%title' => $category->title, '%feed_title' => $feed['title']))); + + // Assert that no broken links (associated with the deleted category) + // appear on one of the other category pages. + $this->createSampleNodes(); + $this->drupalGet('admin/config/services/aggregator'); + $this->clickLink('update items'); + $categories = $this->getCategories(); + $category = reset($categories); + $this->drupalGet('aggregator/categories/' . $category->cid); + global $base_path; + $this->assertNoRaw(','); } + } /** @@ -685,9 +709,21 @@ class CategorizeFeedItemTestCase extends AggregatorTestCase { } } + // Delete category from feed items when category is deleted. + $cid = reset($feed->categories); + $categories = $this->getCategories(); + $category_title = $categories[$cid]->title; + + // Delete category. + aggregator_save_category(array('cid' => $cid)); + + // Assert category has been removed from feed items. + $categorized_count = db_query("SELECT COUNT(*) FROM {aggregator_category_item} WHERE cid = :cid", array(':cid' => $cid))->fetchField(); + $this->assertFalse($categorized_count, format_string('The category %title has been removed from feed items.', array('%title' => $category_title))); // Delete feed. $this->deleteFeed($feed); } + } /** diff --git a/modules/aggregator/tests/aggregator_test.info b/modules/aggregator/tests/aggregator_test.info index 4983896..575be56 100644 --- a/modules/aggregator/tests/aggregator_test.info +++ b/modules/aggregator/tests/aggregator_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/block/block.info b/modules/block/block.info index 9e47f1f..a0ff83f 100644 --- a/modules/block/block.info +++ b/modules/block/block.info @@ -6,8 +6,8 @@ core = 7.x files[] = block.test configure = admin/structure/block -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/block/block.module b/modules/block/block.module index 73e1162..d68ea9e 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -432,23 +432,20 @@ function _block_rehash($theme = NULL) { drupal_alter('block_info', $current_blocks, $theme, $code_blocks); foreach ($current_blocks as $module => $module_blocks) { foreach ($module_blocks as $delta => $block) { - if (!isset($block['pages'])) { - // {block}.pages is type 'text', so it cannot have a - // default value, and not null, so we need to provide - // value if the module did not. - $block['pages'] = ''; - } - // Make sure weight is set. - if (!isset($block['weight'])) { - $block['weight'] = 0; - } + // Make sure certain attributes are set. + $block += array( + 'pages' => '', + 'weight' => 0, + 'status' => 0, + ); + // Check for active blocks in regions that are not available. if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) { drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning'); // Disabled modules are moved into the BLOCK_REGION_NONE later so no // need to move the block to another region. $block['status'] = 0; } - // Set region to none if not enabled and make sure status is set. + // Set region to none if not enabled. if (empty($block['status'])) { $block['status'] = 0; $block['region'] = BLOCK_REGION_NONE; diff --git a/modules/block/tests/block_test.info b/modules/block/tests/block_test.info index ef1f713..beff596 100644 --- a/modules/block/tests/block_test.info +++ b/modules/block/tests/block_test.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/block/tests/themes/block_test_theme/block_test_theme.info b/modules/block/tests/themes/block_test_theme/block_test_theme.info index be82747..6e7b9c9 100644 --- a/modules/block/tests/themes/block_test_theme/block_test_theme.info +++ b/modules/block/tests/themes/block_test_theme/block_test_theme.info @@ -13,8 +13,8 @@ regions[footer] = Footer regions[highlighted] = Highlighted regions[help] = Help -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/blog/blog.info b/modules/blog/blog.info index 0302f22..d241eca 100644 --- a/modules/blog/blog.info +++ b/modules/blog/blog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = blog.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/book/book.info b/modules/book/book.info index 396bd66..164043d 100644 --- a/modules/book/book.info +++ b/modules/book/book.info @@ -7,8 +7,8 @@ files[] = book.test configure = admin/content/book/settings stylesheets[all][] = book.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/color/color.info b/modules/color/color.info index 2b58810..086f8cf 100644 --- a/modules/color/color.info +++ b/modules/color/color.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = color.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/comment/comment.info b/modules/comment/comment.info index 69885db..3dbf6e6 100644 --- a/modules/comment/comment.info +++ b/modules/comment/comment.info @@ -9,8 +9,8 @@ files[] = comment.test configure = admin/content/comment stylesheets[all][] = comment.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/contact/contact.info b/modules/contact/contact.info index 464c224..466e941 100644 --- a/modules/contact/contact.info +++ b/modules/contact/contact.info @@ -6,8 +6,8 @@ core = 7.x files[] = contact.test configure = admin/structure/contact -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/contact/contact.module b/modules/contact/contact.module index 9a48f23..9c6671a 100644 --- a/modules/contact/contact.module +++ b/modules/contact/contact.module @@ -234,7 +234,14 @@ function contact_form_user_profile_form_alter(&$form, &$form_state) { * Implements hook_user_presave(). */ function contact_user_presave(&$edit, $account, $category) { - $edit['data']['contact'] = isset($edit['contact']) ? $edit['contact'] : variable_get('contact_default_status', 1); + if (isset($edit['contact'])) { + // Set new value. + $edit['data']['contact'] = $edit['contact']; + } + elseif (!isset($account->data['contact'])) { + // Use default if none has been set. + $edit['data']['contact'] = variable_get('contact_default_status', 1); + } } /** diff --git a/modules/contact/contact.test b/modules/contact/contact.test index 6693b57..6a1674a 100644 --- a/modules/contact/contact.test +++ b/modules/contact/contact.test @@ -346,6 +346,28 @@ class ContactPersonalTestCase extends DrupalWebTestCase { $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); $this->assertResponse(200); + // Test that users can disable their contact form. + $this->drupalLogin($this->contact_user); + $edit = array('contact' => FALSE); + $this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save'); + $this->drupalLogout(); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(403); + + // Test that user's contact status stays disabled when saving. + $contact_user_temp = user_load($this->contact_user->uid, TRUE); + user_save($contact_user_temp); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(403); + + // Test that users can enable their contact form. + $this->drupalLogin($this->contact_user); + $edit = array('contact' => TRUE); + $this->drupalPost('user/' . $this->contact_user->uid . '/edit', $edit, 'Save'); + $this->drupalLogout(); + $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); + $this->assertResponse(200); + // Revoke the personal contact permission for the anonymous user. user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms')); $this->drupalGet('user/' . $this->contact_user->uid . '/contact'); diff --git a/modules/contextual/contextual.info b/modules/contextual/contextual.info index b57e9f6..fd73edd 100644 --- a/modules/contextual/contextual.info +++ b/modules/contextual/contextual.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = contextual.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/dashboard/dashboard.info b/modules/dashboard/dashboard.info index d17a974..bc9c98a 100644 --- a/modules/dashboard/dashboard.info +++ b/modules/dashboard/dashboard.info @@ -7,8 +7,8 @@ files[] = dashboard.test dependencies[] = block configure = admin/dashboard/customize -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/dblog/dblog.info b/modules/dblog/dblog.info index 89b66c1..dc39510 100644 --- a/modules/dblog/dblog.info +++ b/modules/dblog/dblog.info @@ -5,8 +5,8 @@ version = VERSION core = 7.x files[] = dblog.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/field.info b/modules/field/field.info index d19c29d..241c297 100644 --- a/modules/field/field.info +++ b/modules/field/field.info @@ -11,8 +11,8 @@ dependencies[] = field_sql_storage required = TRUE stylesheets[all][] = theme/field.css -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/field_sql_storage/field_sql_storage.info b/modules/field/modules/field_sql_storage/field_sql_storage.info index a35372a..48881e2 100644 --- a/modules/field/modules/field_sql_storage/field_sql_storage.info +++ b/modules/field/modules/field_sql_storage/field_sql_storage.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = field_sql_storage.test required = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/list/list.info b/modules/field/modules/list/list.info index 0cd4939..e7427bc 100644 --- a/modules/field/modules/list/list.info +++ b/modules/field/modules/list/list.info @@ -7,8 +7,8 @@ dependencies[] = field dependencies[] = options files[] = tests/list.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/list/tests/list_test.info b/modules/field/modules/list/tests/list_test.info index 4bd2dae..ce3ca4c 100644 --- a/modules/field/modules/list/tests/list_test.info +++ b/modules/field/modules/list/tests/list_test.info @@ -5,8 +5,8 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/number/number.info b/modules/field/modules/number/number.info index d3c995e..39a3364 100644 --- a/modules/field/modules/number/number.info +++ b/modules/field/modules/number/number.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = number.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/options/options.info b/modules/field/modules/options/options.info index d395377..bb21283 100644 --- a/modules/field/modules/options/options.info +++ b/modules/field/modules/options/options.info @@ -6,8 +6,8 @@ core = 7.x dependencies[] = field files[] = options.test -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/modules/text/text.info b/modules/field/modules/text/text.info index 678bdab..86dcdc7 100644 --- a/modules/field/modules/text/text.info +++ b/modules/field/modules/text/text.info @@ -7,8 +7,8 @@ dependencies[] = field files[] = text.test required = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/tests/field_test.info b/modules/field/tests/field_test.info index 07eed53..54ea80f 100644 --- a/modules/field/tests/field_test.info +++ b/modules/field/tests/field_test.info @@ -6,8 +6,8 @@ files[] = field_test.entity.inc version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-02-01 -version = "7.54" +; Information added by Drupal.org packaging script on 2017-06-21 +version = "7.56" project = "drupal" -datestamp = "1485986921" +datestamp = "1498069849" diff --git a/modules/field/theme/field.tpl.php b/modules/field/theme/field.tpl.php index f0f9d58..460fd2e 100644 --- a/modules/field/theme/field.tpl.php +++ b/modules/field/theme/field.tpl.php @@ -4,8 +4,10 @@ * @file field.tpl.php * Default template implementation to display the value of a field. * - * This file is not used and is here as a starting point for customization only. - * @see theme_field() + * This file is not used by Drupal core, which uses theme functions instead for + * performance reasons. The markup is the same, though, so if you want to use + * template files rather than functions to extend field theming, copy this to + * your custom theme. See theme_field() for a discussion of performance. * * Available variables: * - $items: An array of field values. Use render() to output them. @@ -45,7 +47,7 @@ */ ?>