Browse Source

updated core to 7.56, secutity update

Bachir Soussi Chiadmi 6 years ago
parent
commit
5c7f02554f
100 changed files with 575 additions and 301 deletions
  1. 20 0
      CHANGELOG.txt
  2. 7 2
      includes/bootstrap.inc
  3. 1 1
      includes/common.inc
  4. 6 6
      includes/database/pgsql/database.inc
  5. 1 1
      includes/database/pgsql/install.inc
  6. 2 2
      includes/database/pgsql/select.inc
  7. 3 3
      includes/database/query.inc
  8. 4 1
      includes/database/schema.inc
  9. 6 7
      includes/database/sqlite/query.inc
  10. 1 1
      includes/database/sqlite/schema.inc
  11. 3 3
      includes/errors.inc
  12. 26 3
      includes/file.inc
  13. 69 16
      misc/drupal.js
  14. 3 3
      modules/aggregator/aggregator.info
  15. 8 0
      modules/aggregator/aggregator.module
  16. 37 1
      modules/aggregator/aggregator.test
  17. 3 3
      modules/aggregator/tests/aggregator_test.info
  18. 3 3
      modules/block/block.info
  19. 8 11
      modules/block/block.module
  20. 3 3
      modules/block/tests/block_test.info
  21. 3 3
      modules/block/tests/themes/block_test_theme/block_test_theme.info
  22. 3 3
      modules/blog/blog.info
  23. 3 3
      modules/book/book.info
  24. 3 3
      modules/color/color.info
  25. 3 3
      modules/comment/comment.info
  26. 3 3
      modules/contact/contact.info
  27. 8 1
      modules/contact/contact.module
  28. 22 0
      modules/contact/contact.test
  29. 3 3
      modules/contextual/contextual.info
  30. 3 3
      modules/dashboard/dashboard.info
  31. 3 3
      modules/dblog/dblog.info
  32. 3 3
      modules/field/field.info
  33. 3 3
      modules/field/modules/field_sql_storage/field_sql_storage.info
  34. 3 3
      modules/field/modules/list/list.info
  35. 3 3
      modules/field/modules/list/tests/list_test.info
  36. 3 3
      modules/field/modules/number/number.info
  37. 3 3
      modules/field/modules/options/options.info
  38. 3 3
      modules/field/modules/text/text.info
  39. 3 3
      modules/field/tests/field_test.info
  40. 5 3
      modules/field/theme/field.tpl.php
  41. 3 3
      modules/field_ui/field_ui.info
  42. 3 3
      modules/file/file.info
  43. 4 3
      modules/file/file.module
  44. 74 0
      modules/file/tests/file.test
  45. 3 3
      modules/file/tests/file_module_test.info
  46. 3 3
      modules/filter/filter.info
  47. 3 3
      modules/forum/forum.info
  48. 3 3
      modules/help/help.info
  49. 3 3
      modules/image/image.info
  50. 3 3
      modules/image/tests/image_module_test.info
  51. 3 3
      modules/locale/locale.info
  52. 3 3
      modules/locale/locale.test
  53. 3 3
      modules/locale/tests/locale_test.info
  54. 3 3
      modules/menu/menu.info
  55. 3 3
      modules/node/node.info
  56. 3 3
      modules/node/tests/node_access_test.info
  57. 3 3
      modules/node/tests/node_test.info
  58. 3 3
      modules/node/tests/node_test_exception.info
  59. 3 3
      modules/openid/openid.info
  60. 3 3
      modules/openid/tests/openid_test.info
  61. 3 3
      modules/overlay/overlay.info
  62. 3 3
      modules/path/path.info
  63. 3 3
      modules/php/php.info
  64. 3 3
      modules/poll/poll.info
  65. 3 3
      modules/profile/profile.info
  66. 3 3
      modules/rdf/rdf.info
  67. 3 3
      modules/rdf/tests/rdf_test.info
  68. 3 3
      modules/search/search.info
  69. 3 3
      modules/search/tests/search_embedded_form.info
  70. 3 3
      modules/search/tests/search_extra_type.info
  71. 3 3
      modules/search/tests/search_node_tags.info
  72. 3 3
      modules/shortcut/shortcut.info
  73. 28 4
      modules/simpletest/drupal_web_test_case.php
  74. 3 3
      modules/simpletest/simpletest.info
  75. 3 3
      modules/simpletest/tests/actions_loop_test.info
  76. 3 3
      modules/simpletest/tests/ajax_forms_test.info
  77. 3 3
      modules/simpletest/tests/ajax_test.info
  78. 3 3
      modules/simpletest/tests/batch_test.info
  79. 3 3
      modules/simpletest/tests/boot_test_1.info
  80. 3 3
      modules/simpletest/tests/boot_test_2.info
  81. 1 1
      modules/simpletest/tests/common.test
  82. 3 3
      modules/simpletest/tests/common_test.info
  83. 3 3
      modules/simpletest/tests/common_test_cron_helper.info
  84. 3 3
      modules/simpletest/tests/database_test.info
  85. 3 3
      modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info
  86. 3 3
      modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
  87. 3 3
      modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
  88. 3 3
      modules/simpletest/tests/entity_cache_test.info
  89. 3 3
      modules/simpletest/tests/entity_cache_test_dependency.info
  90. 3 3
      modules/simpletest/tests/entity_crud_hook_test.info
  91. 3 3
      modules/simpletest/tests/entity_query_access_test.info
  92. 3 3
      modules/simpletest/tests/error_test.info
  93. 3 3
      modules/simpletest/tests/file_test.info
  94. 3 3
      modules/simpletest/tests/filter_test.info
  95. 3 3
      modules/simpletest/tests/form_test.info
  96. 3 3
      modules/simpletest/tests/image_test.info
  97. 3 3
      modules/simpletest/tests/menu_test.info
  98. 3 3
      modules/simpletest/tests/module_test.info
  99. 3 3
      modules/simpletest/tests/path_test.info
  100. 3 3
      modules/simpletest/tests/psr_0_test/psr_0_test.info

+ 20 - 0
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
 Drupal 7.54, 2017-02-01
 -----------------------
 -----------------------
 - Modules are now able to define theme engines (API addition:
 - Modules are now able to define theme engines (API addition:

+ 7 - 2
includes/bootstrap.inc

@@ -8,7 +8,7 @@
 /**
 /**
  * The current system version.
  * The current system version.
  */
  */
-define('VERSION', '7.54');
+define('VERSION', '7.56');
 
 
 /**
 /**
  * Core API compatibility.
  * 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
  * http://tools.ietf.org/html/rfc7231#section-7.1.1.1
  *
  *
  * Example: Sun, 06 Nov 1994 08:49:37 GMT
  * 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.
  * Provides a caching wrapper to be used in place of large array structures.

+ 1 - 1
includes/common.inc

@@ -487,7 +487,7 @@ function drupal_http_build_query(array $query, $parent = '') {
   $params = array();
   $params = array();
 
 
   foreach ($query as $key => $value) {
   foreach ($query as $key => $value) {
-    $key = ($parent ? $parent . '[' . rawurlencode($key) . ']' : rawurlencode($key));
+    $key = $parent ? $parent . rawurlencode('[' . $key . ']') : rawurlencode($key);
 
 
     // Recurse into children.
     // Recurse into children.
     if (is_array($value)) {
     if (is_array($value)) {

+ 6 - 6
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);
 define('POSTGRESQL_NEXTID_LOCK', 1000);
 
 
@@ -55,7 +55,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
     $connection_options['pdo'] += array(
     $connection_options['pdo'] += array(
       // Prepared statements are most effective for performance when queries
       // Prepared statements are most effective for performance when queries
       // are recycled (used several times). However, if they are not re-used,
       // 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
       // prepared queries are not re-used, it should be faster to emulate
       // the preparation than to actually ready statements for re-use. If in
       // the preparation than to actually ready statements for re-use. If in
       // doubt, reset to FALSE and measure performance.
       // 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
    * PostgreSQL has built in sequences. We'll use these instead of inserting
    * and updating a sequences table.
    * and updating a sequences table.
    */
    */
   public function nextId($existing = 0) {
   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.
     // because the prefix may change, for example, like it does in simpletests.
     $sequence_name = $this->makeSequenceName('sequences', 'value');
     $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
     // 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.
     // from altering the sequence while we are.
     $this->query("SELECT pg_advisory_lock(" . POSTGRESQL_NEXTID_LOCK . ")");
     $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.
     // Reset the sequence to a higher value than the existing id.
     $this->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));
     $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();
     $id = $this->query("SELECT nextval('" . $sequence_name . "')")->fetchField();
 
 
     $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");
     $this->query("SELECT pg_advisory_unlock(" . POSTGRESQL_NEXTID_LOCK . ")");

+ 1 - 1
includes/database/pgsql/install.inc

@@ -165,7 +165,7 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
         LANGUAGE \'sql\''
         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
       // database drivers for Drupal that do not support the syntax, however
       // they do support CONCAT(item1, item2) which we can replicate in
       // they do support CONCAT(item1, item2) which we can replicate in
       // PostgreSQL. PostgreSQL requires the function to be defined for each
       // PostgreSQL. PostgreSQL requires the function to be defined for each

+ 2 - 2
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
     // 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
     // twice: Once through table_alias.* and once directly. If the field
     // actually belongs to a different table, it must be added manually.
     // actually belongs to a different table, it must be added manually.
     foreach ($this->tables as $table) {
     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
     // 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.
     // either.
     if ($this->connection->escapeField($field) != $field) {
     if ($this->connection->escapeField($field) != $field) {
       return $return;
       return $return;

+ 3 - 3
includes/database/query.inc

@@ -845,8 +845,8 @@ class DeleteQuery extends Query implements QueryConditionInterface {
   /**
   /**
    * Executes the DELETE query.
    * 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() {
   public function execute() {
     $values = array();
     $values = array();
@@ -1242,7 +1242,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
  * MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
  * MergeQuery::updateFields() and MergeQuery::insertFields() needs to be called
  * instead. MergeQuery::fields() can also be called which calls both of these
  * 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
  * 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
  * wrapper is MergeQuery::key() which adds the same column-value pairs to the
  * condition and the INSERT query part.
  * condition and the INSERT query part.
  *
  *

+ 4 - 1
includes/database/schema.inc

@@ -164,6 +164,9 @@ require_once dirname(__FILE__) . '/query.inc';
  * @see drupal_install_schema()
  * @see drupal_install_schema()
  */
  */
 
 
+/**
+ * Base class for database schema definitions.
+ */
 abstract class DatabaseSchema implements QueryPlaceholderInterface {
 abstract class DatabaseSchema implements QueryPlaceholderInterface {
 
 
   protected $connection;
   protected $connection;
@@ -291,7 +294,7 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
   protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
   protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
     $info = $this->connection->getConnectionOptions();
     $info = $this->connection->getConnectionOptions();
 
 
-    // Retrive the table name and schema
+    // Retrieve the table name and schema
     $table_info = $this->getPrefixInfo($table_name, $add_prefix);
     $table_info = $this->getPrefixInfo($table_name, $add_prefix);
 
 
     $condition = new DatabaseCondition('AND');
     $condition = new DatabaseCondition('AND');

+ 6 - 7
includes/database/sqlite/query.inc

@@ -99,16 +99,15 @@ class UpdateQuery_sqlite extends UpdateQuery {
 
 
 /**
 /**
  * SQLite specific implementation of DeleteQuery.
  * 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 {
 class DeleteQuery_sqlite extends DeleteQuery {
   public function execute() {
   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)) {
     if (!count($this->condition)) {
       $total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
       $total_rows = $this->connection->query('SELECT COUNT(*) FROM {' . $this->connection->escapeTable($this->table) . '}')->fetchField();
       parent::execute();
       parent::execute();

+ 1 - 1
includes/database/sqlite/schema.inc

@@ -244,7 +244,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
     // database. So the syntax '...RENAME TO database.table' would fail.
     // database. So the syntax '...RENAME TO database.table' would fail.
     // So we must determine the full table name here rather than surrounding
     // So we must determine the full table name here rather than surrounding
     // the table with curly braces incase the db_prefix contains a reference
     // 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);
     $info = $this->getPrefixInfo($new_name);
     $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
     $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO ' . $info['table']);
 
 

+ 3 - 3
includes/errors.inc

@@ -66,7 +66,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c
     _drupal_log_error(array(
     _drupal_log_error(array(
       '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
       '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
       // The standard PHP error handler considers that the error messages
       // 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),
       '!message' => filter_xss_admin($message),
       '%function' => $caller['function'],
       '%function' => $caller['function'],
       '%file' => $caller['file'],
       '%file' => $caller['file'],
@@ -114,7 +114,7 @@ function _drupal_decode_exception($exception) {
   return array(
   return array(
     '%type' => get_class($exception),
     '%type' => get_class($exception),
     // The standard PHP exception handler considers that the exception message
     // 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),
     '!message' => check_plain($message),
     '%function' => $caller['function'],
     '%function' => $caller['function'],
     '%file' => $caller['file'],
     '%file' => $caller['file'],
@@ -233,7 +233,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
   }
   }
   else {
   else {
     // Display the message if the current error reporting level allows this type
     // 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)) {
     if (error_displayable($error)) {
       $class = 'error';
       $class = 'error';
 
 

+ 26 - 3
includes/file.inc

@@ -535,7 +535,18 @@ SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
 EOF;
 EOF;
 
 
   if ($private) {
   if ($private) {
-    $lines = "Deny from all\n\n" . $lines;
+    $lines = <<<EOF
+# Deny all requests from Apache 2.4+.
+<IfModule mod_authz_core.c>
+  Require all denied
+</IfModule>
+
+# Deny all requests from Apache 2.0-2.2.
+<IfModule !mod_authz_core.c>
+  Deny from all
+</IfModule>
+EOF
+    . "\n\n" . $lines;
   }
   }
 
 
   return $lines;
   return $lines;
@@ -889,7 +900,6 @@ function file_valid_uri($uri) {
  */
  */
 function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
 function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
   $original_source = $source;
   $original_source = $source;
-  $original_destination = $destination;
 
 
   // Assert that the source file actually exists.
   // Assert that the source file actually exists.
   if (!file_exists($source)) {
   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 we made it this far it's safe to record this file in the database.
   if ($file = file_save($file)) {
   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.
     // Add file to the cache.
     $upload_cache[$form_field_name] = $file;
     $upload_cache[$form_field_name] = $file;
     return $file;
     return $file;
@@ -2553,7 +2577,6 @@ function file_directory_temp() {
  *   An associative array of headers, as expected by file_transfer().
  *   An associative array of headers, as expected by file_transfer().
  */
  */
 function file_get_content_headers($file) {
 function file_get_content_headers($file) {
-  $name = mime_header_encode($file->filename);
   $type = mime_header_encode($file->filemime);
   $type = mime_header_encode($file->filemime);
 
 
   return array(
   return array(

+ 69 - 16
misc/drupal.js

@@ -168,23 +168,76 @@ Drupal.checkPlain = function (str) {
 Drupal.formatString = function(str, args) {
 Drupal.formatString = function(str, args) {
   // Transform arguments before inserting them.
   // Transform arguments before inserting them.
   for (var key in args) {
   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.
  *   A translated string.
  */
  */
 Drupal.formatPlural = function (count, singular, plural, args, options) {
 Drupal.formatPlural = function (count, singular, plural, args, options) {
-  var args = args || {};
+  args = args || {};
   args['@count'] = count;
   args['@count'] = count;
   // Determine the index of the plural form.
   // Determine the index of the plural form.
   var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
   var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);

+ 3 - 3
modules/aggregator/aggregator.info

@@ -7,8 +7,8 @@ files[] = aggregator.test
 configure = admin/config/services/aggregator/settings
 configure = admin/config/services/aggregator/settings
 stylesheets[all][] = aggregator.css
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 8 - 0
modules/aggregator/aggregator.module

@@ -455,6 +455,14 @@ function aggregator_save_category($edit) {
       db_delete('aggregator_category')
       db_delete('aggregator_category')
         ->condition('cid', $edit['cid'])
         ->condition('cid', $edit['cid'])
         ->execute();
         ->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.
       // Make sure there is no active block for this category.
       if (module_exists('block')) {
       if (module_exists('block')) {
         db_delete('block')
         db_delete('block')

+ 37 - 1
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() {
   function testCategorizeFeed() {
 
 
@@ -448,7 +448,31 @@ class CategorizeFeedTestCase extends AggregatorTestCase {
     // Assert the feed has two categories.
     // Assert the feed has two categories.
     $this->getFeedCategories($db_feed);
     $this->getFeedCategories($db_feed);
     $this->assertEqual(count($db_feed->categories), 2, 'Feed has 2 categories');
     $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('<a href="' . $base_path . 'aggregator/categories/"></a>,');
   }
   }
+
 }
 }
 
 
 /**
 /**
@@ -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.
     // Delete feed.
     $this->deleteFeed($feed);
     $this->deleteFeed($feed);
   }
   }
+
 }
 }
 
 
 /**
 /**

+ 3 - 3
modules/aggregator/tests/aggregator_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/block/block.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = block.test
 files[] = block.test
 configure = admin/structure/block
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 8 - 11
modules/block/block.module

@@ -432,23 +432,20 @@ function _block_rehash($theme = NULL) {
   drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
   drupal_alter('block_info', $current_blocks, $theme, $code_blocks);
   foreach ($current_blocks as $module => $module_blocks) {
   foreach ($current_blocks as $module => $module_blocks) {
     foreach ($module_blocks as $delta => $block) {
     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) {
       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');
         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
         // Disabled modules are moved into the BLOCK_REGION_NONE later so no
         // need to move the block to another region.
         // need to move the block to another region.
         $block['status'] = 0;
         $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'])) {
       if (empty($block['status'])) {
         $block['status'] = 0;
         $block['status'] = 0;
         $block['region'] = BLOCK_REGION_NONE;
         $block['region'] = BLOCK_REGION_NONE;

+ 3 - 3
modules/block/tests/block_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/block/tests/themes/block_test_theme/block_test_theme.info

@@ -13,8 +13,8 @@ regions[footer] = Footer
 regions[highlighted] = Highlighted
 regions[highlighted] = Highlighted
 regions[help] = Help
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/blog/blog.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = blog.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/book/book.info

@@ -7,8 +7,8 @@ files[] = book.test
 configure = admin/content/book/settings
 configure = admin/content/book/settings
 stylesheets[all][] = book.css
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/color/color.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = color.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/comment/comment.info

@@ -9,8 +9,8 @@ files[] = comment.test
 configure = admin/content/comment
 configure = admin/content/comment
 stylesheets[all][] = comment.css
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/contact/contact.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = contact.test
 files[] = contact.test
 configure = admin/structure/contact
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 8 - 1
modules/contact/contact.module

@@ -234,7 +234,14 @@ function contact_form_user_profile_form_alter(&$form, &$form_state) {
  * Implements hook_user_presave().
  * Implements hook_user_presave().
  */
  */
 function contact_user_presave(&$edit, $account, $category) {
 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);
+  }
 }
 }
 
 
 /**
 /**

+ 22 - 0
modules/contact/contact.test

@@ -346,6 +346,28 @@ class ContactPersonalTestCase extends DrupalWebTestCase {
     $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
     $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
     $this->assertResponse(200);
     $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.
     // Revoke the personal contact permission for the anonymous user.
     user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
     user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access user contact forms'));
     $this->drupalGet('user/' . $this->contact_user->uid . '/contact');
     $this->drupalGet('user/' . $this->contact_user->uid . '/contact');

+ 3 - 3
modules/contextual/contextual.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = contextual.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/dashboard/dashboard.info

@@ -7,8 +7,8 @@ files[] = dashboard.test
 dependencies[] = block
 dependencies[] = block
 configure = admin/dashboard/customize
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/dblog/dblog.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = dblog.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/field.info

@@ -11,8 +11,8 @@ dependencies[] = field_sql_storage
 required = TRUE
 required = TRUE
 stylesheets[all][] = theme/field.css
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/field_sql_storage/field_sql_storage.info

@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = field_sql_storage.test
 files[] = field_sql_storage.test
 required = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/list/list.info

@@ -7,8 +7,8 @@ dependencies[] = field
 dependencies[] = options
 dependencies[] = options
 files[] = tests/list.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/list/tests/list_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/number/number.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 dependencies[] = field
 files[] = number.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/options/options.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 dependencies[] = field
 files[] = options.test
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/modules/text/text.info

@@ -7,8 +7,8 @@ dependencies[] = field
 files[] = text.test
 files[] = text.test
 required = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/field/tests/field_test.info

@@ -6,8 +6,8 @@ files[] = field_test.entity.inc
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 5 - 3
modules/field/theme/field.tpl.php

@@ -4,8 +4,10 @@
  * @file field.tpl.php
  * @file field.tpl.php
  * Default template implementation to display the value of a field.
  * 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:
  * Available variables:
  * - $items: An array of field values. Use render() to output them.
  * - $items: An array of field values. Use render() to output them.
@@ -45,7 +47,7 @@
  */
  */
 ?>
 ?>
 <!--
 <!--
-THIS FILE IS NOT USED AND IS HERE AS A STARTING POINT FOR CUSTOMIZATION ONLY.
+This file is not used by Drupal core, which uses theme functions instead.
 See http://api.drupal.org/api/function/theme_field/7 for details.
 See http://api.drupal.org/api/function/theme_field/7 for details.
 After copying this file to your theme's folder and customizing it, remove this
 After copying this file to your theme's folder and customizing it, remove this
 HTML comment.
 HTML comment.

+ 3 - 3
modules/field_ui/field_ui.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 dependencies[] = field
 files[] = field_ui.test
 files[] = field_ui.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/file/file.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = field
 dependencies[] = field
 files[] = tests/file.test
 files[] = tests/file.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 4 - 3
modules/file/file.module

@@ -146,8 +146,9 @@ function file_file_download($uri, $field_type = 'file') {
   // headers for files controlled by other modules. Make an exception for
   // headers for files controlled by other modules. Make an exception for
   // temporary files where the host entity has not yet been saved (for example,
   // temporary files where the host entity has not yet been saved (for example,
   // an image preview on a node/add form) in which case, allow download by the
   // an image preview on a node/add form) in which case, allow download by the
-  // file's owner.
-  if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid)) {
+  // file's owner. For anonymous file owners, only the browser session that
+  // uploaded the file should be granted access.
+  if (empty($references) && ($file->status == FILE_STATUS_PERMANENT || $file->uid != $user->uid || (!$user->uid && empty($_SESSION['anonymous_allowed_file_ids'][$file->fid])))) {
       return;
       return;
   }
   }
 
 
@@ -283,7 +284,7 @@ function file_ajax_upload() {
   $form['#prefix'] .= theme('status_messages');
   $form['#prefix'] .= theme('status_messages');
   $output = drupal_render($form);
   $output = drupal_render($form);
   $js = drupal_add_js();
   $js = drupal_add_js();
-  $settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
+  $settings = drupal_array_merge_deep_array($js['settings']['data']);
 
 
   $commands[] = ajax_command_replace(NULL, $output, $settings);
   $commands[] = ajax_command_replace(NULL, $output, $settings);
   return array('#type' => 'ajax', '#commands' => $commands);
   return array('#type' => 'ajax', '#commands' => $commands);

+ 74 - 0
modules/file/tests/file.test

@@ -1551,6 +1551,80 @@ class FilePrivateTestCase extends FileFieldTestCase {
     $this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
     $this->assertNoRaw($node_file->filename, 'File without view field access permission does not appear after attempting to attach it to a new node.');
     $this->drupalGet(file_create_url($node_file->uri));
     $this->drupalGet(file_create_url($node_file->uri));
     $this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
     $this->assertResponse(403, 'Confirmed that access is denied for the file without view field access permission after attempting to attach it to a new node.');
+
+    // As an anonymous user, create a temporary file with no references and
+    // confirm that only the session that uploaded it may view it.
+    $this->drupalLogout();
+    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array(
+      "create $type_name content",
+      'access content',
+    ));
+    $test_file = $this->getTestFile('text');
+    $this->drupalGet('node/add/' . $type_name);
+    $edit = array('files[' . $field_name . '_' . LANGUAGE_NONE . '_0]' => drupal_realpath($test_file->uri));
+    $this->drupalPost(NULL, $edit, t('Upload'));
+    $files = file_load_multiple(array(), array('uid' => 0));
+    $this->assertEqual(1, count($files), 'Loaded one anonymous file.');
+    $file = end($files);
+    $this->assertNotEqual($file->status, FILE_STATUS_PERMANENT, 'File is temporary.');
+    $usage = file_usage_list($file);
+    $this->assertFalse($usage, 'No file usage found.');
+    $file_url = file_create_url($file->uri);
+    $this->drupalGet($file_url);
+    $this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the temporary file.');
+    // Close the prior connection and remove the session cookie.
+    $this->curlClose();
+    $this->cookies = array();
+    $this->drupalGet($file_url);
+    $this->assertResponse(403, 'Confirmed that another anonymous user cannot access the temporary file.');
+
+    // As an anonymous user, create a permanent file that is referenced by a
+    // published node and confirm that all anonymous users may view it.
+    $test_file = $this->getTestFile('text');
+    $this->drupalGet('node/add/' . $type_name);
+    $edit = array();
+    $edit['title'] = $this->randomName();
+    $edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $new_node = $this->drupalGetNodeByTitle($edit['title']);
+    $file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
+    $this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
+    $usage = file_usage_list($file);
+    $this->assertTrue($usage, 'File usage found.');
+    $file_url = file_create_url($file->uri);
+    $this->drupalGet($file_url);
+    $this->assertResponse(200, 'Confirmed that the anonymous uploader has access to the permanent file that is referenced by a published node.');
+    // Close the prior connection and remove the session cookie.
+    $this->curlClose();
+    $this->cookies = array();
+    $this->drupalGet($file_url);
+    $this->assertResponse(200, 'Confirmed that another anonymous user also has access to the permanent file that is referenced by a published node.');
+
+    // As an anonymous user, create a permanent file that is referenced by an
+    // unpublished node and confirm that no anonymous users may view it (even
+    // the session that uploaded the file) because they cannot view the
+    // unpublished node.
+    $test_file = $this->getTestFile('text');
+    $this->drupalGet('node/add/' . $type_name);
+    $edit = array();
+    $edit['title'] = $this->randomName();
+    $edit['files[' . $field_name . '_' . LANGUAGE_NONE . '_0]'] = drupal_realpath($test_file->uri);
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $new_node = $this->drupalGetNodeByTitle($edit['title']);
+    $new_node->status = NODE_NOT_PUBLISHED;
+    node_save($new_node);
+    $file = file_load($new_node->{$field_name}[LANGUAGE_NONE][0]['fid']);
+    $this->assertEqual($file->status, FILE_STATUS_PERMANENT, 'File is permanent.');
+    $usage = file_usage_list($file);
+    $this->assertTrue($usage, 'File usage found.');
+    $file_url = file_create_url($file->uri);
+    $this->drupalGet($file_url);
+    $this->assertResponse(403, 'Confirmed that the anonymous uploader cannot access the permanent file when it is referenced by an unpublished node.');
+    // Close the prior connection and remove the session cookie.
+    $this->curlClose();
+    $this->cookies = array();
+    $this->drupalGet($file_url);
+    $this->assertResponse(403, 'Confirmed that another anonymous user cannot access the permanent file when it is referenced by an unpublished node.');
   }
   }
 }
 }
 
 

+ 3 - 3
modules/file/tests/file_module_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/filter/filter.info

@@ -7,8 +7,8 @@ files[] = filter.test
 required = TRUE
 required = TRUE
 configure = admin/config/content/formats
 configure = admin/config/content/formats
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/forum/forum.info

@@ -9,8 +9,8 @@ files[] = forum.test
 configure = admin/structure/forum
 configure = admin/structure/forum
 stylesheets[all][] = forum.css
 stylesheets[all][] = forum.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/help/help.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = help.test
 files[] = help.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/image/image.info

@@ -7,8 +7,8 @@ dependencies[] = file
 files[] = image.test
 files[] = image.test
 configure = admin/config/media/image-styles
 configure = admin/config/media/image-styles
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/image/tests/image_module_test.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = image_module_test.module
 files[] = image_module_test.module
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/locale/locale.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = locale.test
 files[] = locale.test
 configure = admin/config/regional/language
 configure = admin/config/regional/language
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/locale/locale.test

@@ -819,7 +819,7 @@ class LocalePluralFormatTest extends DrupalWebTestCase {
    *   Additional options to pass to the translation import form.
    *   Additional options to pass to the translation import form.
    */
    */
   function importPoFile($contents, array $options = array()) {
   function importPoFile($contents, array $options = array()) {
-    $name = tempnam('temporary://', "po_") . '.po';
+    $name = drupal_tempnam('temporary://', "po_") . '.po';
     file_put_contents($name, $contents);
     file_put_contents($name, $contents);
     $options['files[file]'] = $name;
     $options['files[file]'] = $name;
     $this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
     $this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
@@ -1113,7 +1113,7 @@ class LocaleImportFunctionalTest extends DrupalWebTestCase {
    *   Additional options to pass to the translation import form.
    *   Additional options to pass to the translation import form.
    */
    */
   function importPoFile($contents, array $options = array()) {
   function importPoFile($contents, array $options = array()) {
-    $name = tempnam('temporary://', "po_") . '.po';
+    $name = drupal_tempnam('temporary://', "po_") . '.po';
     file_put_contents($name, $contents);
     file_put_contents($name, $contents);
     $options['files[file]'] = $name;
     $options['files[file]'] = $name;
     $this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
     $this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
@@ -1340,7 +1340,7 @@ class LocaleExportFunctionalTest extends DrupalWebTestCase {
   function testExportTranslation() {
   function testExportTranslation() {
     // First import some known translations.
     // First import some known translations.
     // This will also automatically enable the 'fr' language.
     // This will also automatically enable the 'fr' language.
-    $name = tempnam('temporary://', "po_") . '.po';
+    $name = drupal_tempnam('temporary://', "po_") . '.po';
     file_put_contents($name, $this->getPoFile());
     file_put_contents($name, $this->getPoFile());
     $this->drupalPost('admin/config/regional/translate/import', array(
     $this->drupalPost('admin/config/regional/translate/import', array(
       'langcode' => 'fr',
       'langcode' => 'fr',

+ 3 - 3
modules/locale/tests/locale_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/menu/menu.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = menu.test
 files[] = menu.test
 configure = admin/structure/menu
 configure = admin/structure/menu
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/node/node.info

@@ -9,8 +9,8 @@ required = TRUE
 configure = admin/structure/types
 configure = admin/structure/types
 stylesheets[all][] = node.css
 stylesheets[all][] = node.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/node/tests/node_access_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/node/tests/node_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/node/tests/node_test_exception.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/openid/openid.info

@@ -5,8 +5,8 @@ package = Core
 core = 7.x
 core = 7.x
 files[] = openid.test
 files[] = openid.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/openid/tests/openid_test.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = openid
 dependencies[] = openid
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/overlay/overlay.info

@@ -4,8 +4,8 @@ package = Core
 version = VERSION
 version = VERSION
 core = 7.x
 core = 7.x
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/path/path.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = path.test
 files[] = path.test
 configure = admin/config/search/path
 configure = admin/config/search/path
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/php/php.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = php.test
 files[] = php.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/poll/poll.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = poll.test
 files[] = poll.test
 stylesheets[all][] = poll.css
 stylesheets[all][] = poll.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/profile/profile.info

@@ -11,8 +11,8 @@ configure = admin/config/people/profile
 ; See user_system_info_alter().
 ; See user_system_info_alter().
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/rdf/rdf.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 files[] = rdf.test
 files[] = rdf.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/rdf/tests/rdf_test.info

@@ -6,8 +6,8 @@ core = 7.x
 hidden = TRUE
 hidden = TRUE
 dependencies[] = blog
 dependencies[] = blog
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/search/search.info

@@ -8,8 +8,8 @@ files[] = search.test
 configure = admin/config/search/settings
 configure = admin/config/search/settings
 stylesheets[all][] = search.css
 stylesheets[all][] = search.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/search/tests/search_embedded_form.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/search/tests/search_extra_type.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/search/tests/search_node_tags.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/shortcut/shortcut.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = shortcut.test
 files[] = shortcut.test
 configure = admin/config/user-interface/shortcut
 configure = admin/config/user-interface/shortcut
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 28 - 4
modules/simpletest/drupal_web_test_case.php

@@ -39,6 +39,13 @@ abstract class DrupalTestCase {
    */
    */
   protected $originalFileDirectory = NULL;
   protected $originalFileDirectory = NULL;
 
 
+  /**
+   * URL to the verbose output file directory.
+   *
+   * @var string
+   */
+  protected $verboseDirectoryUrl;
+
   /**
   /**
    * Time limit for the test.
    * Time limit for the test.
    */
    */
@@ -461,8 +468,11 @@ abstract class DrupalTestCase {
   protected function verbose($message) {
   protected function verbose($message) {
     if ($id = simpletest_verbose($message)) {
     if ($id = simpletest_verbose($message)) {
       $class_safe = str_replace('\\', '_', get_class($this));
       $class_safe = str_replace('\\', '_', get_class($this));
-      $url = file_create_url($this->originalFileDirectory . '/simpletest/verbose/' . $class_safe . '-' . $id . '.html');
-      $this->error(l(t('Verbose message'), $url, array('attributes' => array('target' => '_blank'))), 'User notice');
+      $url = $this->verboseDirectoryUrl . '/' . $class_safe . '-' . $id . '.html';
+      // Not using l() to avoid invoking the theme system, so that unit tests
+      // can use verbose() as well.
+      $link = '<a href="' . $url . '" target="_blank">' . t('Verbose message') . '</a>';
+      $this->error($link, 'User notice');
     }
     }
   }
   }
 
 
@@ -719,10 +729,17 @@ class DrupalUnitTestCase extends DrupalTestCase {
    * method.
    * method.
    */
    */
   protected function setUp() {
   protected function setUp() {
-    global $conf;
+    global $conf, $language;
 
 
     // Store necessary current values before switching to the test environment.
     // Store necessary current values before switching to the test environment.
     $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
     $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
+    $this->verboseDirectoryUrl = file_create_url($this->originalFileDirectory . '/simpletest/verbose');
+
+    // Set up English language.
+    $this->originalLanguage = $language;
+    $this->originalLanguageDefault = variable_get('language_default');
+    unset($conf['language_default']);
+    $language = language_default();
 
 
     // Reset all statics so that test is performed with a clean environment.
     // Reset all statics so that test is performed with a clean environment.
     drupal_static_reset();
     drupal_static_reset();
@@ -764,7 +781,7 @@ class DrupalUnitTestCase extends DrupalTestCase {
   }
   }
 
 
   protected function tearDown() {
   protected function tearDown() {
-    global $conf;
+    global $conf, $language;
 
 
     // Get back to the original connection.
     // Get back to the original connection.
     Database::removeConnection('default');
     Database::removeConnection('default');
@@ -775,6 +792,12 @@ class DrupalUnitTestCase extends DrupalTestCase {
     if (isset($this->originalModuleList)) {
     if (isset($this->originalModuleList)) {
       module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
       module_list(TRUE, FALSE, FALSE, $this->originalModuleList);
     }
     }
+
+    // Reset language.
+    $language = $this->originalLanguage;
+    if ($this->originalLanguageDefault) {
+      $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault;
+    }
   }
   }
 }
 }
 
 
@@ -1381,6 +1404,7 @@ class DrupalWebTestCase extends DrupalTestCase {
     $this->originalLanguageUrl = $language_url;
     $this->originalLanguageUrl = $language_url;
     $this->originalLanguageDefault = variable_get('language_default');
     $this->originalLanguageDefault = variable_get('language_default');
     $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
     $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
+    $this->verboseDirectoryUrl = file_create_url($this->originalFileDirectory . '/simpletest/verbose');
     $this->originalProfile = drupal_get_profile();
     $this->originalProfile = drupal_get_profile();
     $this->originalCleanUrl = variable_get('clean_url', 0);
     $this->originalCleanUrl = variable_get('clean_url', 0);
     $this->originalUser = $user;
     $this->originalUser = $user;

+ 3 - 3
modules/simpletest/simpletest.info

@@ -57,8 +57,8 @@ files[] = tests/upgrade/update.trigger.test
 files[] = tests/upgrade/update.field.test
 files[] = tests/upgrade/update.field.test
 files[] = tests/upgrade/update.user.test
 files[] = tests/upgrade/update.user.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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/actions_loop_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/ajax_forms_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/ajax_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/batch_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/boot_test_1.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/boot_test_2.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 1 - 1
modules/simpletest/tests/common.test

@@ -169,7 +169,7 @@ class CommonURLUnitTest extends DrupalWebTestCase {
     $this->assertEqual(drupal_http_build_query(array('a' => ' &#//+%20@۞')), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.');
     $this->assertEqual(drupal_http_build_query(array('a' => ' &#//+%20@۞')), 'a=%20%26%23//%2B%2520%40%DB%9E', 'Value was properly encoded.');
     $this->assertEqual(drupal_http_build_query(array(' &#//+%20@۞' => 'a')), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.');
     $this->assertEqual(drupal_http_build_query(array(' &#//+%20@۞' => 'a')), '%20%26%23%2F%2F%2B%2520%40%DB%9E=a', 'Key was properly encoded.');
     $this->assertEqual(drupal_http_build_query(array('a' => '1', 'b' => '2', 'c' => '3')), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.');
     $this->assertEqual(drupal_http_build_query(array('a' => '1', 'b' => '2', 'c' => '3')), 'a=1&b=2&c=3', 'Multiple values were properly concatenated.');
-    $this->assertEqual(drupal_http_build_query(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo')), 'a[b]=2&a[c]=3&d=foo', 'Nested array was properly encoded.');
+    $this->assertEqual(drupal_http_build_query(array('a' => array('b' => '2', 'c' => '3'), 'd' => 'foo')), 'a%5Bb%5D=2&a%5Bc%5D=3&d=foo', 'Nested array was properly encoded.');
   }
   }
 
 
   /**
   /**

+ 3 - 3
modules/simpletest/tests/common_test.info

@@ -7,8 +7,8 @@ stylesheets[all][] = common_test.css
 stylesheets[print][] = common_test.print.css
 stylesheets[print][] = common_test.print.css
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/common_test_cron_helper.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/database_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info

@@ -7,8 +7,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/entity_cache_test.info

@@ -6,8 +6,8 @@ core = 7.x
 dependencies[] = entity_cache_test_dependency
 dependencies[] = entity_cache_test_dependency
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/entity_cache_test_dependency.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/entity_crud_hook_test.info

@@ -5,8 +5,8 @@ package = Testing
 version = VERSION
 version = VERSION
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/entity_query_access_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/error_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/file_test.info

@@ -6,8 +6,8 @@ core = 7.x
 files[] = file_test.module
 files[] = file_test.module
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/filter_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/form_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/image_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/menu_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/module_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/path_test.info

@@ -5,8 +5,8 @@ version = VERSION
 core = 7.x
 core = 7.x
 hidden = TRUE
 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

+ 3 - 3
modules/simpletest/tests/psr_0_test/psr_0_test.info

@@ -5,8 +5,8 @@ core = 7.x
 hidden = TRUE
 hidden = TRUE
 package = Testing
 package = Testing
 
 
-; 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"
 project = "drupal"
-datestamp = "1485986921"
+datestamp = "1498069849"
 
 

Some files were not shown because too many files changed in this diff