diff -Naur drupal-7.56/CHANGELOG.txt drupal-7.66/CHANGELOG.txt --- drupal-7.56/CHANGELOG.txt 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/CHANGELOG.txt 2019-04-17 22:20:46.000000000 +0200 @@ -1,3 +1,66 @@ +Drupal 7.xx, xxxx-xx-xx (development version) +----------------------- + +Drupal 7.66, 2019-04-17 +----------------------- +- Fixed security issues: + - SA-CORE-2019-006 + +Drupal 7.65, 2019-03-20 +----------------------- +- Fixed security issues: + - SA-CORE-2019-004 + +Drupal 7.64, 2019-02-06 +----------------------- +- [regression] Unset the 'host' header in drupal_http_request() during redirect +- Fixed: 7.x does not have Phar protection and Phar tests are failing on Drupal 7 +- Fixed: Notice: Undefined index: display_field in file_field_widget_value() (line 582 of /module/file/file.field.inc) +- Performance improvement: Registry rebuild should not parse the same file twice in the same request +- Fixed _registry_update() to clear caches after transaction is committed + +Drupal 7.63, 2019-01-16 +----------------------- +- Fixed a fatal error for some Drush users introduced by SA-CORE-2019-002. + +Drupal 7.62, 2019-01-15 +----------------------- +- Fixed security issues: + - SA-CORE-2019-001 + - SA-CORE-2019-002 + +Drupal 7.61, 2018-11-07 +----------------------- +- File upload validation functions and hook_file_validate() implementations are + now always passed the correct file URI. +- The default form cache expiration of 6 hours is now configurable (API + addition: https://www.drupal.org/node/2857751). +- Allowed callers of drupal_http_request() to optionally specify an explicit + Host header. +- Allowed the + character to appear in usernames. +- PHP 7.2: Fixed Archive_Tar incompatibility. +- PHP 7.2: Removed deprecated function each(). +- PHP 7.2: Avoid count() calls on uncountable variables. +- PHP 7.2: Removed deprecated create_function() call. +- PHP 7.2: Make sure variables are arrays in theme_links(). +- Fixed theme-settings.php not being loaded on cached forms +- Fixed problem with IE11 & Chrome(PointerEvents enabled) & some Firefox scroll to the top of the page after dragging the bottom item with jquery 1.5 <-> 1.11 + +Drupal 7.60, 2018-10-18 +------------------------ +- Fixed security issues. See SA-CORE-2018-006. + +Drupal 7.59, 2018-04-25 +----------------------- +- Fixed security issues (remote code execution). See SA-CORE-2018-004. + +Drupal 7.58, 2018-03-28 +----------------------- +- Fixed security issues (remote code execution). See SA-CORE-2018-002. + +Drupal 7.57, 2018-02-21 +----------------------- +- Fixed security issues (multiple vulnerabilities). See SA-CORE-2018-001. Drupal 7.56, 2017-06-21 ----------------------- diff -Naur drupal-7.56/MAINTAINERS.txt drupal-7.66/MAINTAINERS.txt --- drupal-7.56/MAINTAINERS.txt 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/MAINTAINERS.txt 2019-04-17 22:20:46.000000000 +0200 @@ -15,6 +15,7 @@ - Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx - David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein - Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0 +- (provisional) Pol Dellaiera 'Pol' https://www.drupal.org/u/pol Component maintainers @@ -44,10 +45,9 @@ - Derek Wright 'dww' https://www.drupal.org/u/dww Database system -- Larry Garfield 'Crell' https://www.drupal.org/u/crell +- ? - MySQL driver - - Larry Garfield 'Crell' https://www.drupal.org/u/crell - David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss - PostgreSQL driver diff -Naur drupal-7.56/includes/bootstrap.inc drupal-7.66/includes/bootstrap.inc --- drupal-7.56/includes/bootstrap.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/bootstrap.inc 2019-04-17 22:20:46.000000000 +0200 @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.56'); +define('VERSION', '7.66'); /** * Core API compatibility. @@ -704,6 +704,19 @@ // Set sane locale settings, to ensure consistent string, dates, times and // numbers handling. setlocale(LC_ALL, 'C'); + + // PHP's built-in phar:// stream wrapper is not sufficiently secure. Override + // it with a more secure one, which requires PHP 5.3.3. For lower versions, + // unregister the built-in one without replacing it. Sites needing phar + // support for lower PHP versions must implement hook_stream_wrappers() to + // register their desired implementation. + if (in_array('phar', stream_get_wrappers(), TRUE)) { + stream_wrapper_unregister('phar'); + if (version_compare(PHP_VERSION, '5.3.3', '>=')) { + include_once DRUPAL_ROOT . '/includes/file.phar.inc'; + file_register_phar_wrapper(); + } + } } /** @@ -2632,6 +2645,10 @@ timer_start('page'); // Initialize the configuration, including variables from settings.php. drupal_settings_initialize(); + + // Sanitize unsafe keys from the request. + require_once DRUPAL_ROOT . '/includes/request-sanitizer.inc'; + DrupalRequestSanitizer::sanitize(); } /** @@ -2774,6 +2791,11 @@ unset($_GET['destination']); unset($_REQUEST['destination']); } + // Use the DrupalRequestSanitizer to ensure that the destination's query + // parameters are not dangerous. + if (isset($_GET['destination'])) { + DrupalRequestSanitizer::cleanDestination(); + } // If there's still something in $_REQUEST['destination'] that didn't come // from $_GET, check it too. if (isset($_REQUEST['destination']) && (!isset($_GET['destination']) || $_REQUEST['destination'] != $_GET['destination']) && url_is_external($_REQUEST['destination'])) { @@ -3776,8 +3798,12 @@ chdir(DRUPAL_ROOT); try { - while (list($key, $callback) = each($callbacks)) { + // Manually iterate over the array instead of using a foreach loop. + // A foreach operates on a copy of the array, so any shutdown functions that + // were added from other shutdown functions would never be called. + while ($callback = current($callbacks)) { call_user_func_array($callback['callback'], $callback['arguments']); + next($callbacks); } } catch (Exception $exception) { diff -Naur drupal-7.56/includes/common.inc drupal-7.66/includes/common.inc --- drupal-7.56/includes/common.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/common.inc 2019-04-17 22:20:46.000000000 +0200 @@ -611,8 +611,9 @@ } // The 'q' parameter contains the path of the current page if clean URLs are // disabled. It overrides the 'path' of the URL when present, even if clean - // URLs are enabled, due to how Apache rewriting rules work. - if (isset($options['query']['q'])) { + // URLs are enabled, due to how Apache rewriting rules work. The path + // parameter must be a string. + if (isset($options['query']['q']) && is_string($options['query']['q'])) { $options['path'] = $options['query']['q']; unset($options['query']['q']); } @@ -866,8 +867,10 @@ // Make the socket connection to a proxy server. $socket = 'tcp://' . $proxy_server . ':' . variable_get('proxy_port', 8080); // The Host header still needs to match the real request. - $options['headers']['Host'] = $uri['host']; - $options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : ''; + if (!isset($options['headers']['Host'])) { + $options['headers']['Host'] = $uri['host']; + $options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : ''; + } break; case 'http': @@ -877,14 +880,18 @@ // RFC 2616: "non-standard ports MUST, default ports MAY be included". // We don't add the standard port to prevent from breaking rewrite rules // checking the host that do not take into account the port number. - $options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : ''); + if (!isset($options['headers']['Host'])) { + $options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : ''); + } break; case 'https': // Note: Only works when PHP is compiled with OpenSSL support. $port = isset($uri['port']) ? $uri['port'] : 443; $socket = 'ssl://' . $uri['host'] . ':' . $port; - $options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : ''); + if (!isset($options['headers']['Host'])) { + $options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : ''); + } break; default: @@ -1087,6 +1094,11 @@ elseif ($options['max_redirects']) { // Redirect to the new location. $options['max_redirects']--; + + // We need to unset the 'Host' header + // as we are redirecting to a new location. + unset($options['headers']['Host']); + $result = drupal_http_request($location, $options); $result->redirect_code = $code; } @@ -2236,8 +2248,11 @@ 'prefix' => '' ); + // Determine whether this is an external link, but ensure that the current + // path is always treated as internal by default (to prevent external link + // injection vulnerabilities). if (!isset($options['external'])) { - $options['external'] = url_is_external($path); + $options['external'] = $path === $_GET['q'] ? FALSE : url_is_external($path); } // Preserve the original path before altering or aliasing. @@ -2307,7 +2322,10 @@ $language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : ''; $alias = drupal_get_path_alias($original_path, $language); if ($alias != $original_path) { - $path = $alias; + // Strip leading slashes from internal path aliases to prevent them + // becoming external URLs without protocol. /example.com should not be + // turned into //example.com. + $path = ltrim($alias, '/'); } } diff -Naur drupal-7.56/includes/file.inc drupal-7.66/includes/file.inc --- drupal-7.56/includes/file.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/file.inc 2019-04-17 22:20:46.000000000 +0200 @@ -993,8 +993,15 @@ * @return * The destination filepath, or FALSE if the file already exists * and FILE_EXISTS_ERROR is specified. + * + * @throws RuntimeException + * Thrown if the filename contains invalid UTF-8. */ function file_destination($destination, $replace) { + $basename = drupal_basename($destination); + if (!drupal_validate_utf8($basename)) { + throw new RuntimeException(sprintf("Invalid filename '%s'", $basename)); + } if (file_exists($destination)) { switch ($replace) { case FILE_EXISTS_REPLACE: @@ -1002,7 +1009,6 @@ break; case FILE_EXISTS_RENAME: - $basename = drupal_basename($destination); $directory = drupal_dirname($destination); $destination = file_create_filename($basename, $directory); break; @@ -1218,11 +1224,20 @@ * @return * File path consisting of $directory and a unique filename based off * of $basename. + * + * @throws RuntimeException + * Thrown if the $basename is not valid UTF-8 or another error occurs + * stripping control characters. */ function file_create_filename($basename, $directory) { + $original = $basename; // Strip control characters (ASCII value < 32). Though these are allowed in // some filesystems, not many applications handle them well. $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename); + if (preg_last_error() !== PREG_NO_ERROR) { + throw new RuntimeException(sprintf("Invalid filename '%s'", $original)); + } + if (substr(PHP_OS, 0, 3) == 'WIN') { // These characters are not allowed in Windows filenames $basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename); @@ -1534,9 +1549,9 @@ // rename filename.php.foo and filename.php to filename.php.foo.txt and // filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads' // evaluates to TRUE. - if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { + if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|phar|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { $file->filemime = 'text/plain'; - $file->uri .= '.txt'; + // The destination filename will also later be used to create the URI. $file->filename .= '.txt'; // The .txt extension may not be in the allowed list of extensions. We have // to add it here or else the file upload will fail. @@ -1563,7 +1578,13 @@ if (substr($destination, -1) != '/') { $destination .= '/'; } - $file->destination = file_destination($destination . $file->filename, $replace); + try { + $file->destination = file_destination($destination . $file->filename, $replace); + } + catch (RuntimeException $e) { + drupal_set_message(t('The file %source could not be uploaded because the name is invalid.', array('%source' => $form_field_name)), 'error'); + return FALSE; + } // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and // there's an existing file so we need to bail. if ($file->destination === FALSE) { @@ -2130,9 +2151,33 @@ * 'filename', and 'name' members corresponding to the matching files. */ function file_scan_directory($dir, $mask, $options = array(), $depth = 0) { + // Default nomask option. + $nomask = '/(\.\.?|CVS)$/'; + + // Overrides the $nomask variable accordingly if $options['nomask'] is set. + // + // Allow directories specified in settings.php to be ignored. You can use this + // to not check for files in common special-purpose directories. For example, + // node_modules and bower_components. Ignoring irrelevant directories is a + // performance boost. + if (!isset($options['nomask'])) { + $ignore_directories = variable_get( + 'file_scan_ignore_directories', + array() + ); + + foreach ($ignore_directories as $index => $ignore_directory) { + $ignore_directories[$index] = preg_quote($ignore_directory, '/'); + } + + if (!empty($ignore_directories)) { + $nomask = '/^(\.\.?)|CVS|' . implode('|', $ignore_directories) . '$/'; + } + } + // Merge in defaults. $options += array( - 'nomask' => '/(\.\.?|CVS)$/', + 'nomask' => $nomask, 'callback' => 0, 'recurse' => TRUE, 'key' => 'uri', diff -Naur drupal-7.56/includes/file.phar.inc drupal-7.66/includes/file.phar.inc --- drupal-7.56/includes/file.phar.inc 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/includes/file.phar.inc 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,41 @@ +withAssertion(new PharExtensionInterceptor()) + ); + } + catch (\LogicException $e) { + // Continue if the PharStreamWrapperManager is already initialized. + // For example, this occurs following a drupal_static_reset(), such + // as during tests. + }; + + // To prevent file_stream_wrapper_valid_scheme() treating "phar" as a valid + // scheme, this is registered with PHP only, not with hook_stream_wrappers() + // or the internal storage of file_get_stream_wrappers(). + stream_wrapper_register('phar', '\\TYPO3\\PharStreamWrapper\\PharStreamWrapper'); +} diff -Naur drupal-7.56/includes/form.inc drupal-7.66/includes/form.inc --- drupal-7.56/includes/form.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/form.inc 2019-04-17 22:20:46.000000000 +0200 @@ -555,8 +555,10 @@ * Stores a form in the cache. */ function form_set_cache($form_build_id, $form, $form_state) { - // 6 hours cache life time for forms should be plenty. - $expire = 21600; + // The default cache_form expiration is 6 hours. On busy sites, the cache_form + // table can become very large. A shorter cache lifetime can help to keep the + // table's size under control. + $expire = variable_get('form_cache_expiration', 21600); // Ensure that the form build_id embedded in the form structure is the same as // the one passed in as a parameter. This is an additional safety measure to @@ -1438,10 +1440,12 @@ // length if it's a string, and the item count if it's an array. // An unchecked checkbox has a #value of integer 0, different than string // '0', which could be a valid value. - $is_empty_multiple = (!count($elements['#value'])); + $is_countable = is_array($elements['#value']) || $elements['#value'] instanceof Countable; + $is_empty_multiple = $is_countable && count($elements['#value']) == 0; $is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0); $is_empty_value = ($elements['#value'] === 0); - if ($is_empty_multiple || $is_empty_string || $is_empty_value) { + $is_empty_null = is_null($elements['#value']); + if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_null) { // Although discouraged, a #title is not mandatory for form elements. In // case there is no #title, we cannot set a form error message. // Instead of setting no #title, form constructors are encouraged to set diff -Naur drupal-7.56/includes/install.inc drupal-7.66/includes/install.inc --- drupal-7.56/includes/install.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/install.inc 2019-04-17 22:20:46.000000000 +0200 @@ -779,7 +779,7 @@ $module_list = array_flip(array_values($module_list)); $profile = drupal_get_profile(); - while (list($module) = each($module_list)) { + foreach (array_keys($module_list) as $module) { if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) { // This module doesn't exist or is already uninstalled. Skip it. unset($module_list[$module]); diff -Naur drupal-7.56/includes/menu.inc drupal-7.66/includes/menu.inc --- drupal-7.56/includes/menu.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/menu.inc 2019-04-17 22:20:46.000000000 +0200 @@ -576,7 +576,8 @@ // 'load arguments' in the hook_menu() entry, but they need // some processing. In this case the $function is the key to the // load_function array, and the value is the list of arguments. - list($function, $args) = each($function); + $args = current($function); + $function = key($function); $load_functions[$index] = $function; // Some arguments are placeholders for dynamic items to process. @@ -2402,7 +2403,8 @@ // a stripped down menu tree containing the active trail only, in case // the given menu has not been built in this request yet. $tree = menu_tree_page_data($preferred_link['menu_name'], NULL, TRUE); - list($key, $curr) = each($tree); + $curr = current($tree); + next($tree); } // There is no link for the current path. else { @@ -2432,7 +2434,8 @@ } $tree = $curr['below'] ? $curr['below'] : array(); } - list($key, $curr) = each($tree); + $curr = current($tree); + next($tree); } // Make sure the current page is in the trail to build the page title, by // appending either the preferred link or the menu router item for the diff -Naur drupal-7.56/includes/module.inc drupal-7.66/includes/module.inc --- drupal-7.56/includes/module.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/module.inc 2019-04-17 22:20:46.000000000 +0200 @@ -404,7 +404,11 @@ // Create an associative array with weights as values. $module_list = array_flip(array_values($module_list)); - while (list($module) = each($module_list)) { + // The array is iterated over manually (instead of using a foreach) because + // modules may be added to the list within the loop and we need to process + // them. + while ($module = key($module_list)) { + next($module_list); if (!isset($module_data[$module])) { // This module is not found in the filesystem, abort. return FALSE; @@ -540,7 +544,11 @@ $module_list = array_flip(array_values($module_list)); $profile = drupal_get_profile(); - while (list($module) = each($module_list)) { + // The array is iterated over manually (instead of using a foreach) because + // modules may be added to the list within the loop and we need to process + // them. + while ($module = key($module_list)) { + next($module_list); if (!isset($module_data[$module]) || !$module_data[$module]->status) { // This module doesn't exist or is already disabled, skip it. unset($module_list[$module]); diff -Naur drupal-7.56/includes/registry.inc drupal-7.66/includes/registry.inc --- drupal-7.56/includes/registry.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/registry.inc 2019-04-17 22:20:46.000000000 +0200 @@ -19,7 +19,6 @@ * Does the work for registry_update(). */ function _registry_update() { - // The registry serves as a central autoloader for all classes, including // the database query builders. However, the registry rebuild process // requires write ability to the database, which means having access to the @@ -33,6 +32,11 @@ require_once DRUPAL_ROOT . '/includes/database/select.inc'; require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc'; + // During the first registry rebuild in a request, we check all the files. + // During subsequent rebuilds, we only add new files. It makes the rebuilding + // process faster during installation of modules. + static $check_existing_files = TRUE; + // Get current list of modules and their files. $modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll(); // Get the list of files we are going to parse. @@ -55,6 +59,9 @@ $files["$filename"] = array('module' => '', 'weight' => 0); } + // Initialize an empty array for the unchanged files. + $unchanged_files = array(); + $transaction = db_transaction(); try { // Allow modules to manually modify the list of files before the registry @@ -63,10 +70,19 @@ // list can then be added to the list of files that the registry will parse, // or modify attributes of a file. drupal_alter('registry_files', $files, $modules); + foreach (registry_get_parsed_files() as $filename => $file) { // Add the hash for those files we have already parsed. if (isset($files[$filename])) { - $files[$filename]['hash'] = $file['hash']; + if ($check_existing_files === TRUE) { + $files[$filename]['hash'] = $file['hash']; + } + else { + // Ignore that file for this request, it has been parsed previously + // and it is unlikely it has changed. + unset($files[$filename]); + $unchanged_files[$filename] = $file; + } } else { // Flush the registry of resources in files that are no longer on disc @@ -79,8 +95,12 @@ ->execute(); } } + $parsed_files = _registry_parse_files($files); + // Add unchanged files to the files. + $files += $unchanged_files; + $unchanged_resources = array(); $lookup_cache = array(); if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) { @@ -89,12 +109,10 @@ foreach ($lookup_cache as $key => $file) { // If the file for this cached resource is carried over unchanged from // the last registry build, then we can safely re-cache it. - if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) { + if ($file && isset($files[$file]) && !in_array($file, $parsed_files, TRUE)) { $unchanged_resources[$key] = $file; } } - module_implements('', FALSE, TRUE); - _registry_check_code(REGISTRY_RESET_LOOKUP_CACHE); } catch (Exception $e) { $transaction->rollback(); @@ -102,6 +120,13 @@ throw $e; } + module_implements('', FALSE, TRUE); + _registry_check_code(REGISTRY_RESET_LOOKUP_CACHE); + + // During the next run in this request, don't bother re-checking existing + // files. + $check_existing_files = FALSE; + // We have some unchanged resources, warm up the cache - no need to pay // for looking them up again. if (count($unchanged_resources) > 0) { diff -Naur drupal-7.56/includes/request-sanitizer.inc drupal-7.66/includes/request-sanitizer.inc --- drupal-7.56/includes/request-sanitizer.inc 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/includes/request-sanitizer.inc 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,114 @@ + implode(', ', $get_sanitized_keys))), E_USER_NOTICE); + } + + // Process request body parameters. + $post_sanitized_keys = array(); + $_POST = self::stripDangerousValues($_POST, $whitelist, $post_sanitized_keys); + if ($log_sanitized_keys && $post_sanitized_keys) { + _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from request body parameters (POST): @keys', array('@keys' => implode(', ', $post_sanitized_keys))), E_USER_NOTICE); + } + + // Process cookie parameters. + $cookie_sanitized_keys = array(); + $_COOKIE = self::stripDangerousValues($_COOKIE, $whitelist, $cookie_sanitized_keys); + if ($log_sanitized_keys && $cookie_sanitized_keys) { + _drupal_trigger_error_with_delayed_logging(format_string('Potentially unsafe keys removed from cookie parameters (COOKIE): @keys', array('@keys' => implode(', ', $cookie_sanitized_keys))), E_USER_NOTICE); + } + + $request_sanitized_keys = array(); + $_REQUEST = self::stripDangerousValues($_REQUEST, $whitelist, $request_sanitized_keys); + + self::$sanitized = TRUE; + } + } + + /** + * Removes the destination if it is dangerous. + * + * Note this can only be called after common.inc has been included. + * + * @return bool + * TRUE if the destination has been removed from $_GET, FALSE if not. + */ + public static function cleanDestination() { + $dangerous_keys = array(); + $log_sanitized_keys = variable_get('sanitize_input_logging', FALSE); + + $parts = drupal_parse_url($_GET['destination']); + // If there is a query string, check its query parameters. + if (!empty($parts['query'])) { + $whitelist = variable_get('sanitize_input_whitelist', array()); + + self::stripDangerousValues($parts['query'], $whitelist, $dangerous_keys); + if (!empty($dangerous_keys)) { + // The destination is removed rather than sanitized to mirror the + // handling of external destinations. + unset($_GET['destination']); + unset($_REQUEST['destination']); + if ($log_sanitized_keys) { + trigger_error(format_string('Potentially unsafe destination removed from query string parameters (GET) because it contained the following keys: @keys', array('@keys' => implode(', ', $dangerous_keys)))); + } + return TRUE; + } + } + return FALSE; + } + + /** + * Strips dangerous keys from the provided input. + * + * @param mixed $input + * The input to sanitize. + * @param string[] $whitelist + * An array of keys to whitelist as safe. + * @param string[] $sanitized_keys + * An array of keys that have been removed. + * + * @return mixed + * The sanitized input. + */ + protected static function stripDangerousValues($input, array $whitelist, array &$sanitized_keys) { + if (is_array($input)) { + foreach ($input as $key => $value) { + if ($key !== '' && $key[0] === '#' && !in_array($key, $whitelist, TRUE)) { + unset($input[$key]); + $sanitized_keys[] = $key; + } + else { + $input[$key] = self::stripDangerousValues($input[$key], $whitelist, $sanitized_keys); + } + } + } + return $input; + } + +} diff -Naur drupal-7.56/includes/theme.inc drupal-7.66/includes/theme.inc --- drupal-7.56/includes/theme.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/includes/theme.inc 2019-04-17 22:20:46.000000000 +0200 @@ -1776,13 +1776,13 @@ * http://www.w3.org/TR/WCAG-TECHS/H42.html for more information. */ function theme_links($variables) { - $links = $variables['links']; - $attributes = $variables['attributes']; + $links = (array) $variables['links']; + $attributes = (array) $variables['attributes']; $heading = $variables['heading']; global $language_url; $output = ''; - if (count($links) > 0) { + if (!empty($links)) { // Treat the heading first if it is present to prepend it to the // list of links. if (!empty($heading)) { @@ -1995,7 +1995,7 @@ $empty = $variables['empty']; // Add sticky headers, if applicable. - if (count($header) && $sticky) { + if (!empty($header) && $sticky) { drupal_add_js('misc/tableheader.js'); // Add 'sticky-enabled' class to the table to identify it for JS. // This is needed to target tables constructed by this function. @@ -2009,7 +2009,7 @@ } // Format the table columns: - if (count($colgroups)) { + if (!empty($colgroups)) { foreach ($colgroups as $number => $colgroup) { $attributes = array(); @@ -2044,38 +2044,40 @@ } // Add the 'empty' row message if available. - if (!count($rows) && $empty) { + if (empty($rows) && $empty) { $header_count = 0; - foreach ($header as $header_cell) { - if (is_array($header_cell)) { - $header_count += isset($header_cell['colspan']) ? $header_cell['colspan'] : 1; - } - else { - $header_count++; + if (!empty($header)) { + foreach ($header as $header_cell) { + if (is_array($header_cell)) { + $header_count += isset($header_cell['colspan']) ? $header_cell['colspan'] : 1; + } + else { + $header_count++; + } } } $rows[] = array(array('data' => $empty, 'colspan' => $header_count, 'class' => array('empty', 'message'))); } // Format the table header: - if (count($header)) { + if (!empty($header)) { $ts = tablesort_init($header); // HTML requires that the thead tag has tr tags in it followed by tbody // tags. Using ternary operator to check and see if we have any rows. - $output .= (count($rows) ? ' ' : ' '); + $output .= (!empty($rows) ? ' ' : ' '); foreach ($header as $cell) { $cell = tablesort_header($cell, $header, $ts); $output .= _theme_table_cell($cell, TRUE); } // Using ternary operator to close the tags based on whether or not there are rows - $output .= (count($rows) ? " \n" : "\n"); + $output .= (!empty($rows) ? " \n" : "\n"); } else { $ts = array(); } // Format the table rows: - if (count($rows)) { + if (!empty($rows)) { $output .= "\n"; $flip = array('even' => 'odd', 'odd' => 'even'); $class = 'even'; @@ -2095,7 +2097,7 @@ $attributes = array(); $no_striping = FALSE; } - if (count($cells)) { + if (!empty($cells)) { // Add odd/even class if (!$no_striping) { $class = $flip[$class]; diff -Naur drupal-7.56/misc/drupal.js drupal-7.66/misc/drupal.js --- drupal-7.56/misc/drupal.js 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/misc/drupal.js 2019-04-17 22:20:46.000000000 +0200 @@ -28,6 +28,42 @@ $.fn.init.prototype = jquery_init.prototype; /** + * Pre-filter Ajax requests to guard against XSS attacks. + * + * See https://github.com/jquery/jquery/issues/2432 + */ +if ($.ajaxPrefilter) { + // For newer versions of jQuery, use an Ajax prefilter to prevent + // auto-executing script tags from untrusted domains. This is similar to the + // fix that is built in to jQuery 3.0 and higher. + $.ajaxPrefilter(function (s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); +} +else if ($.httpData) { + // For the version of jQuery that ships with Drupal core, override + // jQuery.httpData to prevent auto-detecting "script" data types from + // untrusted domains. + var jquery_httpData = $.httpData; + $.httpData = function (xhr, type, s) { + // @todo Consider backporting code from newer jQuery versions to check for + // a cross-domain request here, rather than using Drupal.urlIsLocal() to + // block scripts from all URLs that are not on the same site. + if (!type && !Drupal.urlIsLocal(s.url)) { + var content_type = xhr.getResponseHeader('content-type') || ''; + if (content_type.indexOf('javascript') >= 0) { + // Default to a safe data type. + type = 'text'; + } + } + return jquery_httpData.call(this, xhr, type, s); + }; + $.httpData.prototype = jquery_httpData.prototype; +} + +/** * Attach all registered behaviors to a page element. * * Behaviors are event-triggered actions that attach to page elements, enhancing @@ -137,7 +173,7 @@ */ Drupal.checkPlain = function (str) { var character, regex, - replace = { '&': '&', '"': '"', '<': '<', '>': '>' }; + replace = { '&': '&', "'": ''', '"': '"', '<': '<', '>': '>' }; str = String(str); for (character in replace) { if (replace.hasOwnProperty(character)) { diff -Naur drupal-7.56/misc/jquery-extend-3.4.0.js drupal-7.66/misc/jquery-extend-3.4.0.js --- drupal-7.56/misc/jquery-extend-3.4.0.js 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/jquery-extend-3.4.0.js 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,112 @@ +/** + * For jQuery versions less than 3.4.0, this replaces the jQuery.extend + * function with the one from jQuery 3.4.0, slightly modified (documented + * below) to be compatible with older jQuery versions and browsers. + * + * This provides the Object.prototype pollution vulnerability fix to Drupal + * installations running older jQuery versions, including the versions shipped + * with Drupal core and https://www.drupal.org/project/jquery_update. + * + * @see https://github.com/jquery/jquery/pull/4333 + */ + +(function (jQuery) { + +// Do not override jQuery.extend() if the jQuery version is already >=3.4.0. +var versionParts = jQuery.fn.jquery.split('.'); +var majorVersion = parseInt(versionParts[0]); +var minorVersion = parseInt(versionParts[1]); +var patchVersion = parseInt(versionParts[2]); +var isPreReleaseVersion = (patchVersion.toString() !== versionParts[2]); +if ( + (majorVersion > 3) || + (majorVersion === 3 && minorVersion > 4) || + (majorVersion === 3 && minorVersion === 4 && patchVersion > 0) || + (majorVersion === 3 && minorVersion === 4 && patchVersion === 0 && !isPreReleaseVersion) +) { + return; +} + +/** + * This is almost verbatim copied from jQuery 3.4.0. + * + * Only two minor changes have been made: + * - The call to isFunction() is changed to jQuery.isFunction(). + * - The two calls to Array.isArray() is changed to jQuery.isArray(). + * + * The above two changes ensure compatibility with all older jQuery versions + * (1.4.4 - 3.3.1) and older browser versions (e.g., IE8). + */ +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !jQuery.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +})(jQuery); diff -Naur drupal-7.56/misc/tabledrag.js drupal-7.66/misc/tabledrag.js --- drupal-7.56/misc/tabledrag.js 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/misc/tabledrag.js 2019-04-17 22:20:46.000000000 +0200 @@ -580,21 +580,43 @@ * Get the mouse coordinates from the event (allowing for browser differences). */ Drupal.tableDrag.prototype.mouseCoords = function (event) { + + // Match both null and undefined, but not zero, by using != null. + // See https://stackoverflow.com/questions/2647867/how-to-determine-if-variable-is-undefined-or-null + if (event.pageX != null && event.pageY != null) { + return {x: event.pageX, y: event.pageY}; + } + // Complete support for pointer events was only introduced to jQuery in // version 1.11.1; between versions 1.7 and 1.11.0 pointer events have the - // clientX and clientY properties undefined. In those cases, the properties - // must be retrieved from the event.originalEvent object instead. - var clientX = event.clientX || event.originalEvent.clientX; - var clientY = event.clientY || event.originalEvent.clientY; - - if (event.pageX || event.pageY) { - return { x: event.pageX, y: event.pageY }; + // pageX and pageY properties undefined. In those cases, the properties must + // be retrieved from the event.originalEvent object instead. + if (event.originalEvent && event.originalEvent.pageX != null && event.originalEvent.pageY != null) { + return {x: event.originalEvent.pageX, y: event.originalEvent.pageY}; + } + + // Some old browsers do not support MouseEvent.pageX and *.pageY at all. + // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY + // For those, we look at event.clientX and event.clientY instead. + if (event.clientX == null || event.clientY == null) { + // In some jQuery versions, some events created by jQuery do not have + // clientX and clientY. But the original event might have. + if (!event.originalEvent) { + throw new Error("The event has no coordinates, and no event.originalEvent."); + } + event = event.originalEvent; + if (event.clientX == null || event.clientY == null) { + throw new Error("The original event has no coordinates."); + } } - return { - x: clientX + document.body.scrollLeft - document.body.clientLeft, - y: clientY + document.body.scrollTop - document.body.clientTop - }; + // Copied from jQuery.event.fix() in jQuery 1.4.1. + // In newer jQuery versions, this code is in jQuery.event.mouseHooks.filter(). + var doc = document.documentElement, body = document.body; + var pageX = event.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + var pageY = event.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + + return {x: pageX, y: pageY}; }; /** diff -Naur drupal-7.56/misc/typo3/drupal-security/PharExtensionInterceptor.php drupal-7.66/misc/typo3/drupal-security/PharExtensionInterceptor.php --- drupal-7.56/misc/typo3/drupal-security/PharExtensionInterceptor.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/drupal-security/PharExtensionInterceptor.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,79 @@ +baseFileContainsPharExtension($path)) { + return TRUE; + } + throw new Exception( + sprintf( + 'Unexpected file extension in "%s"', + $path + ), + 1535198703 + ); + } + + /** + * Determines if a path has a .phar extension or invoked execution. + * + * @param string $path + * The path of the phar file to check. + * + * @return bool + * TRUE if the file has a .phar extension or if the execution has been + * invoked by the phar file. + */ + private function baseFileContainsPharExtension($path) { + $baseFile = Helper::determineBaseFile($path); + if ($baseFile === NULL) { + return FALSE; + } + // If the stream wrapper is registered by invoking a phar file that does + // not not have .phar extension then this should be allowed. For + // example, some CLI tools recommend removing the extension. + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + // Find the last entry in the backtrace containing a 'file' key as + // sometimes the last caller is executed outside the scope of a file. For + // example, this occurs with shutdown functions. + do { + $caller = array_pop($backtrace); + } while (empty($caller['file']) && !empty($backtrace)); + if (isset($caller['file']) && $baseFile === Helper::determineBaseFile($caller['file'])) { + return TRUE; + } + $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION); + return strtolower($fileExtension) === 'phar'; + } + +} diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/LICENSE drupal-7.66/misc/typo3/phar-stream-wrapper/LICENSE --- drupal-7.56/misc/typo3/phar-stream-wrapper/LICENSE 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/LICENSE 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 TYPO3 project - https://typo3.org/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/README.md drupal-7.66/misc/typo3/phar-stream-wrapper/README.md --- drupal-7.56/misc/typo3/phar-stream-wrapper/README.md 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/README.md 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,155 @@ +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/TYPO3/phar-stream-wrapper/badges/quality-score.png?b=v2)](https://scrutinizer-ci.com/g/TYPO3/phar-stream-wrapper/?branch=v2) +[![Travis CI Build Status](https://travis-ci.org/TYPO3/phar-stream-wrapper.svg?branch=v2)](https://travis-ci.org/TYPO3/phar-stream-wrapper) + +# PHP Phar Stream Wrapper + +## Abstract & History + +Based on Sam Thomas' findings concerning +[insecure deserialization in combination with obfuscation strategies](https://blog.secarma.co.uk/labs/near-phar-dangerous-unserialization-wherever-you-are) +allowing to hide Phar files inside valid image resources, the TYPO3 project +decided back then to introduce a `PharStreamWrapper` to intercept invocations +of the `phar://` stream in PHP and only allow usage for defined locations in +the file system. + +Since the TYPO3 mission statement is **inspiring people to share**, we thought +it would be helpful for others to release our `PharStreamWrapper` as standalone +package to the PHP community. + +The mentioned security issue was reported to TYPO3 on 10th June 2018 by Sam Thomas +and has been addressed concerning the specific attack vector and for this generic +`PharStreamWrapper` in TYPO3 versions 7.6.30 LTS, 8.7.17 LTS and 9.3.1 on 12th +July 2018. + +* https://typo3.org/security/advisory/typo3-core-sa-2018-002/ +* https://blog.secarma.co.uk/labs/near-phar-dangerous-unserialization-wherever-you-are +* https://youtu.be/GePBmsNJw6Y + +## License + +In general the TYPO3 core is released under the GNU General Public License version +2 or any later version (`GPL-2.0-or-later`). In order to avoid licensing issues and +incompatibilities this `PharStreamWrapper` is licenced under the MIT License. In case +you duplicate or modify source code, credits are not required but really appreciated. + +## Credits + +Thanks to [Alex Pott](https://github.com/alexpott), Drupal for creating +back-ports of all sources in order to provide compatibility with PHP v5.3. + +## Installation + +The `PharStreamWrapper` is provided as composer package `typo3/phar-stream-wrapper` +and has minimum requirements of PHP v5.3 ([`v2`](https://github.com/TYPO3/phar-stream-wrapper/tree/v2) branch) and PHP v7.0 ([`master`](https://github.com/TYPO3/phar-stream-wrapper) branch). + +### Installation for PHP v7.0 + +``` +composer require typo3/phar-stream-wrapper ^3.0 +``` + +### Installation for PHP v5.3 + +``` +composer require typo3/phar-stream-wrapper ^2.0 +``` + +## Example + +The following example is bundled within this package, the shown +`PharExtensionInterceptor` denies all stream wrapper invocations files +not having the `.phar` suffix. Interceptor logic has to be individual and +adjusted to according requirements. + +``` +$behavior = new \TYPO3\PharStreamWrapper\Behavior(); +Manager::initialize( + $behavior->withAssertion(new PharExtensionInterceptor()) +); + +if (in_array('phar', stream_get_wrappers())) { + stream_wrapper_unregister('phar'); + stream_wrapper_register('phar', 'TYPO3\\PharStreamWrapper\\PharStreamWrapper'); +} +``` + +* `PharStreamWrapper` defined as class reference will be instantiated each time + `phar://` streams shall be processed. +* `Manager` as singleton pattern being called by `PharStreamWrapper` instances + in order to retrieve individual behavior and settings. +* `Behavior` holds reference to interceptor(s) that shall assert correct/allowed + invocation of a given `$path` for a given `$command`. Interceptors implement + the interface `Assertable`. Interceptors can act individually on following + commands or handle all of them in case not defined specifically: + + `COMMAND_DIR_OPENDIR` + + `COMMAND_MKDIR` + + `COMMAND_RENAME` + + `COMMAND_RMDIR` + + `COMMAND_STEAM_METADATA` + + `COMMAND_STREAM_OPEN` + + `COMMAND_UNLINK` + + `COMMAND_URL_STAT` + +## Interceptor + +The following interceptor is shipped with the package and ready to use in order +to block any Phar invocation of files not having a `.phar` suffix. Besides that +individual interceptors are possible of course. + +``` +class PharExtensionInterceptor implements Assertable +{ + /** + * Determines whether the base file name has a ".phar" suffix. + * + * @param string $path + * @param string $command + * @return bool + * @throws Exception + */ + public function assert($path, $command) + { + if ($this->baseFileContainsPharExtension($path)) { + return true; + } + throw new Exception( + sprintf( + 'Unexpected file extension in "%s"', + $path + ), + 1535198703 + ); + } + + /** + * @param string $path + * @return bool + */ + private function baseFileContainsPharExtension($path) + { + $baseFile = Helper::determineBaseFile($path); + if ($baseFile === null) { + return false; + } + $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION); + return strtolower($fileExtension) === 'phar'; + } +} +``` + +## Helper + +* `Helper::determineBaseFile(string $path)`: Determines base file that can be + accessed using the regular file system. For instance the following path + `phar:///home/user/bundle.phar/content.txt` would be resolved to + `/home/user/bundle.phar`. +* `Helper::resetOpCache()`: Resets PHP's OPcache if enabled as work-around for + issues in `include()` or `require()` calls and OPcache delivering wrong + results. More details can be found in PHP's bug tracker, for instance like + https://bugs.php.net/bug.php?id=66569 + +## Security Contact + +In case of finding additional security issues in the TYPO3 project or in this +`PharStreamWrapper` package in particular, please get in touch with the +[TYPO3 Security Team](mailto:security@typo3.org). diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/composer.json drupal-7.66/misc/typo3/phar-stream-wrapper/composer.json --- drupal-7.56/misc/typo3/phar-stream-wrapper/composer.json 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/composer.json 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,24 @@ +{ + "name": "typo3/phar-stream-wrapper", + "description": "Interceptors for PHP's native phar:// stream handling", + "type": "library", + "license": "MIT", + "homepage": "https://typo3.org/", + "keywords": ["php", "phar", "stream-wrapper", "security"], + "require": { + "php": "^5.3.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "autoload": { + "psr-4": { + "TYPO3\\PharStreamWrapper\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "TYPO3\\PharStreamWrapper\\Tests\\": "tests/" + } + } +} diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/src/Assertable.php drupal-7.66/misc/typo3/phar-stream-wrapper/src/Assertable.php --- drupal-7.56/misc/typo3/phar-stream-wrapper/src/Assertable.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/src/Assertable.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,22 @@ +assertCommands($commands); + $commands = $commands ?: $this->availableCommands; + + $target = clone $this; + foreach ($commands as $command) { + $target->assertions[$command] = $assertable; + } + return $target; + } + + /** + * @param string $path + * @param string $command + * @return bool + */ + public function assert($path, $command) + { + $this->assertCommand($command); + $this->assertAssertionCompleteness(); + + return $this->assertions[$command]->assert($path, $command); + } + + /** + * @param array $commands + */ + private function assertCommands(array $commands) + { + $unknownCommands = array_diff($commands, $this->availableCommands); + if (empty($unknownCommands)) { + return; + } + throw new \LogicException( + sprintf( + 'Unknown commands: %s', + implode(', ', $unknownCommands) + ), + 1535189881 + ); + } + + private function assertCommand($command) + { + if (in_array($command, $this->availableCommands, true)) { + return; + } + throw new \LogicException( + sprintf( + 'Unknown command "%s"', + $command + ), + 1535189882 + ); + } + + private function assertAssertionCompleteness() + { + $undefinedAssertions = array_diff( + $this->availableCommands, + array_keys($this->assertions) + ); + if (empty($undefinedAssertions)) { + return; + } + throw new \LogicException( + sprintf( + 'Missing assertions for commands: %s', + implode(', ', $undefinedAssertions) + ), + 1535189883 + ); + } +} diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/src/Exception.php drupal-7.66/misc/typo3/phar-stream-wrapper/src/Exception.php --- drupal-7.56/misc/typo3/phar-stream-wrapper/src/Exception.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/src/Exception.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,16 @@ += 1) { + // Rremove this and previous element + array_splice($pathParts, $partCount - 1, 2); + $partCount -= 2; + $pathPartsLength -= 2; + } elseif ($absolutePathPrefix) { + // can't go higher than root dir + // simply remove this part and continue + array_splice($pathParts, $partCount, 1); + $partCount--; + $pathPartsLength--; + } + } + } + + return $absolutePathPrefix . implode('/', $pathParts); + } + + /** + * Checks if the $path is absolute or relative (detecting either '/' or + * 'x:/' as first part of string) and returns TRUE if so. + * + * @param string $path File path to evaluate + * @return bool + */ + private static function isAbsolutePath($path) + { + // Path starting with a / is always absolute, on every system + // On Windows also a path starting with a drive letter is absolute: X:/ + return (isset($path[0]) ? $path[0] : null) === '/' + || static::isWindows() && ( + strpos($path, ':/') === 1 + || strpos($path, ':\\') === 1 + ); + } + + /** + * @return bool + */ + private static function isWindows() + { + return stripos(PHP_OS, 'WIN') === 0; + } +} \ No newline at end of file diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/src/Interceptor/PharExtensionInterceptor.php drupal-7.66/misc/typo3/phar-stream-wrapper/src/Interceptor/PharExtensionInterceptor.php --- drupal-7.56/misc/typo3/phar-stream-wrapper/src/Interceptor/PharExtensionInterceptor.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/src/Interceptor/PharExtensionInterceptor.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,55 @@ +baseFileContainsPharExtension($path)) { + return true; + } + throw new Exception( + sprintf( + 'Unexpected file extension in "%s"', + $path + ), + 1535198703 + ); + } + + /** + * @param string $path + * @return bool + */ + private function baseFileContainsPharExtension($path) + { + $baseFile = Helper::determineBaseFile($path); + if ($baseFile === null) { + return false; + } + $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION); + return strtolower($fileExtension) === 'phar'; + } +} diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/src/Manager.php drupal-7.66/misc/typo3/phar-stream-wrapper/src/Manager.php --- drupal-7.56/misc/typo3/phar-stream-wrapper/src/Manager.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/src/Manager.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,85 @@ +behavior = $behaviour; + } + + /** + * @param string $path + * @param string $command + * @return bool + */ + public function assert($path, $command) + { + return $this->behavior->assert($path, $command); + } +} diff -Naur drupal-7.56/misc/typo3/phar-stream-wrapper/src/PharStreamWrapper.php drupal-7.66/misc/typo3/phar-stream-wrapper/src/PharStreamWrapper.php --- drupal-7.56/misc/typo3/phar-stream-wrapper/src/PharStreamWrapper.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/misc/typo3/phar-stream-wrapper/src/PharStreamWrapper.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,477 @@ +internalResource)) { + return false; + } + + $this->invokeInternalStreamWrapper( + 'closedir', + $this->internalResource + ); + return !is_resource($this->internalResource); + } + + /** + * @param string $path + * @param int $options + * @return bool + */ + public function dir_opendir($path, $options) + { + $this->assert($path, Behavior::COMMAND_DIR_OPENDIR); + $this->internalResource = $this->invokeInternalStreamWrapper( + 'opendir', + $path, + $this->context + ); + return is_resource($this->internalResource); + } + + /** + * @return string|false + */ + public function dir_readdir() + { + return $this->invokeInternalStreamWrapper( + 'readdir', + $this->internalResource + ); + } + + /** + * @return bool + */ + public function dir_rewinddir() + { + if (!is_resource($this->internalResource)) { + return false; + } + + $this->invokeInternalStreamWrapper( + 'rewinddir', + $this->internalResource + ); + return is_resource($this->internalResource); + } + + /** + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + public function mkdir($path, $mode, $options) + { + $this->assert($path, Behavior::COMMAND_MKDIR); + return $this->invokeInternalStreamWrapper( + 'mkdir', + $path, + $mode, + (bool) ($options & STREAM_MKDIR_RECURSIVE), + $this->context + ); + } + + /** + * @param string $path_from + * @param string $path_to + * @return bool + */ + public function rename($path_from, $path_to) + { + $this->assert($path_from, Behavior::COMMAND_RENAME); + $this->assert($path_to, Behavior::COMMAND_RENAME); + return $this->invokeInternalStreamWrapper( + 'rename', + $path_from, + $path_to, + $this->context + ); + } + + /** + * @param string $path + * @param int $options + * @return bool + */ + public function rmdir($path, $options) + { + $this->assert($path, Behavior::COMMAND_RMDIR); + return $this->invokeInternalStreamWrapper( + 'rmdir', + $path, + $this->context + ); + } + + /** + * @param int $cast_as + */ + public function stream_cast($cast_as) + { + throw new Exception( + 'Method stream_select() cannot be used', + 1530103999 + ); + } + + public function stream_close() + { + $this->invokeInternalStreamWrapper( + 'fclose', + $this->internalResource + ); + } + + /** + * @return bool + */ + public function stream_eof() + { + return $this->invokeInternalStreamWrapper( + 'feof', + $this->internalResource + ); + } + + /** + * @return bool + */ + public function stream_flush() + { + return $this->invokeInternalStreamWrapper( + 'fflush', + $this->internalResource + ); + } + + /** + * @param int $operation + * @return bool + */ + public function stream_lock($operation) + { + return $this->invokeInternalStreamWrapper( + 'flock', + $this->internalResource, + $operation + ); + } + + /** + * @param string $path + * @param int $option + * @param string|int $value + * @return bool + */ + public function stream_metadata($path, $option, $value) + { + $this->assert($path, Behavior::COMMAND_STEAM_METADATA); + if ($option === STREAM_META_TOUCH) { + return call_user_func_array( + array($this, 'invokeInternalStreamWrapper'), + array_merge(array('touch', $path), (array) $value) + ); + } + if ($option === STREAM_META_OWNER_NAME || $option === STREAM_META_OWNER) { + return $this->invokeInternalStreamWrapper( + 'chown', + $path, + $value + ); + } + if ($option === STREAM_META_GROUP_NAME || $option === STREAM_META_GROUP) { + return $this->invokeInternalStreamWrapper( + 'chgrp', + $path, + $value + ); + } + if ($option === STREAM_META_ACCESS) { + return $this->invokeInternalStreamWrapper( + 'chmod', + $path, + $value + ); + } + return false; + } + + /** + * @param string $path + * @param string $mode + * @param int $options + * @param string|null $opened_path + * @return bool + */ + public function stream_open( + $path, + $mode, + $options, + &$opened_path = null + ) { + $this->assert($path, Behavior::COMMAND_STREAM_OPEN); + $arguments = array($path, $mode, (bool) ($options & STREAM_USE_PATH)); + // only add stream context for non include/require calls + if (!($options & static::STREAM_OPEN_FOR_INCLUDE)) { + $arguments[] = $this->context; + // work around https://bugs.php.net/bug.php?id=66569 + // for including files from Phar stream with OPcache enabled + } else { + Helper::resetOpCache(); + } + $this->internalResource = call_user_func_array( + array($this, 'invokeInternalStreamWrapper'), + array_merge(array('fopen'), $arguments) + ); + if (!is_resource($this->internalResource)) { + return false; + } + if ($opened_path !== null) { + $metaData = stream_get_meta_data($this->internalResource); + $opened_path = $metaData['uri']; + } + return true; + } + + /** + * @param int $count + * @return string + */ + public function stream_read($count) + { + return $this->invokeInternalStreamWrapper( + 'fread', + $this->internalResource, + $count + ); + } + + /** + * @param int $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence = SEEK_SET) + { + return $this->invokeInternalStreamWrapper( + 'fseek', + $this->internalResource, + $offset, + $whence + ) !== -1; + } + + /** + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + */ + public function stream_set_option($option, $arg1, $arg2) + { + if ($option === STREAM_OPTION_BLOCKING) { + return $this->invokeInternalStreamWrapper( + 'stream_set_blocking', + $this->internalResource, + $arg1 + ); + } + if ($option === STREAM_OPTION_READ_TIMEOUT) { + return $this->invokeInternalStreamWrapper( + 'stream_set_timeout', + $this->internalResource, + $arg1, + $arg2 + ); + } + if ($option === STREAM_OPTION_WRITE_BUFFER) { + return $this->invokeInternalStreamWrapper( + 'stream_set_write_buffer', + $this->internalResource, + $arg2 + ) === 0; + } + return false; + } + + /** + * @return array + */ + public function stream_stat() + { + return $this->invokeInternalStreamWrapper( + 'fstat', + $this->internalResource + ); + } + + /** + * @return int + */ + public function stream_tell() + { + return $this->invokeInternalStreamWrapper( + 'ftell', + $this->internalResource + ); + } + + /** + * @param int $new_size + * @return bool + */ + public function stream_truncate($new_size) + { + return $this->invokeInternalStreamWrapper( + 'ftruncate', + $this->internalResource, + $new_size + ); + } + + /** + * @param string $data + * @return int + */ + public function stream_write($data) + { + return $this->invokeInternalStreamWrapper( + 'fwrite', + $this->internalResource, + $data + ); + } + + /** + * @param string $path + * @return bool + */ + public function unlink($path) + { + $this->assert($path, Behavior::COMMAND_UNLINK); + return $this->invokeInternalStreamWrapper( + 'unlink', + $path, + $this->context + ); + } + + /** + * @param string $path + * @param int $flags + * @return array|false + */ + public function url_stat($path, $flags) + { + $this->assert($path, Behavior::COMMAND_URL_STAT); + $functionName = $flags & STREAM_URL_STAT_QUIET ? '@stat' : 'stat'; + return $this->invokeInternalStreamWrapper($functionName, $path); + } + + /** + * @param string $path + * @param string $command + */ + protected function assert($path, $command) + { + if ($this->resolveAssertable()->assert($path, $command) === true) { + return; + } + + throw new Exception( + sprintf( + 'Denied invocation of "%s" for command "%s"', + $path, + $command + ), + 1535189880 + ); + } + + /** + * @return Assertable + */ + protected function resolveAssertable() + { + return Manager::instance(); + } + + /** + * Invokes commands on the native PHP Phar stream wrapper. + * + * @param string $functionName + * @param mixed ...$arguments + * @return mixed + */ + private function invokeInternalStreamWrapper($functionName) + { + $arguments = func_get_args(); + array_shift($arguments); + $silentExecution = $functionName{0} === '@'; + $functionName = ltrim($functionName, '@'); + $this->restoreInternalSteamWrapper(); + + try { + if ($silentExecution) { + $result = @call_user_func_array($functionName, $arguments); + } else { + $result = call_user_func_array($functionName, $arguments); + } + } catch (\Exception $exception) { + $this->registerStreamWrapper(); + throw $exception; + } catch (\Throwable $throwable) { + $this->registerStreamWrapper(); + throw $throwable; + } + + $this->registerStreamWrapper(); + return $result; + } + + private function restoreInternalSteamWrapper() + { + stream_wrapper_restore('phar'); + } + + private function registerStreamWrapper() + { + stream_wrapper_unregister('phar'); + stream_wrapper_register('phar', get_class($this)); + } +} diff -Naur drupal-7.56/modules/aggregator/aggregator.info drupal-7.66/modules/aggregator/aggregator.info --- drupal-7.56/modules/aggregator/aggregator.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/aggregator/aggregator.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ configure = admin/config/services/aggregator/settings stylesheets[all][] = aggregator.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/aggregator/tests/aggregator_test.info drupal-7.66/modules/aggregator/tests/aggregator_test.info --- drupal-7.56/modules/aggregator/tests/aggregator_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/aggregator/tests/aggregator_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/block/block.info drupal-7.66/modules/block/block.info --- drupal-7.56/modules/block/block.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/block/block.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = block.test configure = admin/structure/block -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/block/tests/block_test.info drupal-7.66/modules/block/tests/block_test.info --- drupal-7.56/modules/block/tests/block_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/block/tests/block_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/block/tests/themes/block_test_theme/block_test_theme.info drupal-7.66/modules/block/tests/themes/block_test_theme/block_test_theme.info --- drupal-7.56/modules/block/tests/themes/block_test_theme/block_test_theme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/block/tests/themes/block_test_theme/block_test_theme.info 2019-04-17 22:39:36.000000000 +0200 @@ -13,8 +13,7 @@ regions[highlighted] = Highlighted regions[help] = Help -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/blog/blog.info drupal-7.66/modules/blog/blog.info --- drupal-7.56/modules/blog/blog.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/blog/blog.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = blog.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/book/book.info drupal-7.66/modules/book/book.info --- drupal-7.56/modules/book/book.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/book/book.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ configure = admin/content/book/settings stylesheets[all][] = book.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/book/book.module drupal-7.66/modules/book/book.module --- drupal-7.56/modules/book/book.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/book/book.module 2019-04-17 22:20:46.000000000 +0200 @@ -768,11 +768,13 @@ return NULL; } $flat = book_get_flat_menu($book_link); - // Assigning the array to $flat resets the array pointer for use with each(). + reset($flat); $curr = NULL; do { $prev = $curr; - list($key, $curr) = each($flat); + $curr = current($flat); + $key = key($flat); + next($flat); } while ($key && $key != $book_link['mlid']); if ($key == $book_link['mlid']) { @@ -806,9 +808,10 @@ */ function book_next($book_link) { $flat = book_get_flat_menu($book_link); - // Assigning the array to $flat resets the array pointer for use with each(). + reset($flat); do { - list($key, $curr) = each($flat); + $key = key($flat); + next($flat); } while ($key && $key != $book_link['mlid']); diff -Naur drupal-7.56/modules/color/color.info drupal-7.66/modules/color/color.info --- drupal-7.56/modules/color/color.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/color/color.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = color.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/comment/comment.info drupal-7.66/modules/comment/comment.info --- drupal-7.56/modules/comment/comment.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/comment/comment.info 2019-04-17 22:39:36.000000000 +0200 @@ -9,8 +9,7 @@ configure = admin/content/comment stylesheets[all][] = comment.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/contact/contact.info drupal-7.66/modules/contact/contact.info --- drupal-7.56/modules/contact/contact.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/contact/contact.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = contact.test configure = admin/structure/contact -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/contextual/contextual.info drupal-7.66/modules/contextual/contextual.info --- drupal-7.56/modules/contextual/contextual.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/contextual/contextual.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = contextual.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/dashboard/dashboard.info drupal-7.66/modules/dashboard/dashboard.info --- drupal-7.56/modules/dashboard/dashboard.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/dashboard/dashboard.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ dependencies[] = block configure = admin/dashboard/customize -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/dblog/dblog.info drupal-7.66/modules/dblog/dblog.info --- drupal-7.56/modules/dblog/dblog.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/dblog/dblog.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = dblog.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/field.info drupal-7.66/modules/field/field.info --- drupal-7.56/modules/field/field.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/field.info 2019-04-17 22:39:36.000000000 +0200 @@ -11,8 +11,7 @@ required = TRUE stylesheets[all][] = theme/field.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/field_sql_storage/field_sql_storage.info drupal-7.66/modules/field/modules/field_sql_storage/field_sql_storage.info --- drupal-7.56/modules/field/modules/field_sql_storage/field_sql_storage.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/field_sql_storage/field_sql_storage.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ files[] = field_sql_storage.test required = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/list/list.info drupal-7.66/modules/field/modules/list/list.info --- drupal-7.56/modules/field/modules/list/list.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/list/list.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ dependencies[] = options files[] = tests/list.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/list/list.install drupal-7.66/modules/field/modules/list/list.install --- drupal-7.56/modules/field/modules/list/list.install 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/field/modules/list/list.install 2019-04-17 22:20:46.000000000 +0200 @@ -61,7 +61,7 @@ // Additionally, float keys need to be disambiguated ('.5' is '0.5'). if ($field['type'] == 'list_number' && !empty($allowed_values)) { - $keys = array_map(create_function('$a', 'return (string) (float) $a;'), array_keys($allowed_values)); + $keys = array_map('_list_update_7001_float_string_cast', array_keys($allowed_values)); $allowed_values = array_combine($keys, array_values($allowed_values)); } @@ -89,6 +89,13 @@ } /** + * Helper callback function to cast the array element. + */ +function _list_update_7001_float_string_cast($element) { + return (string) (float) $element; +} + +/** * Helper function for list_update_7001: extract allowed values from a string. * * This reproduces the parsing logic in use before D7 RC2. diff -Naur drupal-7.56/modules/field/modules/list/tests/list_test.info drupal-7.66/modules/field/modules/list/tests/list_test.info --- drupal-7.56/modules/field/modules/list/tests/list_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/list/tests/list_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/number/number.info drupal-7.66/modules/field/modules/number/number.info --- drupal-7.56/modules/field/modules/number/number.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/number/number.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = field files[] = number.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/number/number.test drupal-7.66/modules/field/modules/number/number.test --- drupal-7.56/modules/field/modules/number/number.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/field/modules/number/number.test 2019-04-17 22:20:46.000000000 +0200 @@ -69,7 +69,7 @@ preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match); $id = $match[1]; $this->assertRaw(t('test_entity @id has been created.', array('@id' => $id)), 'Entity was created'); - $this->assertRaw(round($value, 2), 'Value is displayed.'); + $this->assertRaw($value, 'Value is displayed.'); // Try to create entries with more than one decimal separator; assert fail. $wrong_entries = array( diff -Naur drupal-7.56/modules/field/modules/options/options.info drupal-7.66/modules/field/modules/options/options.info --- drupal-7.56/modules/field/modules/options/options.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/options/options.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = field files[] = options.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/modules/text/text.info drupal-7.66/modules/field/modules/text/text.info --- drupal-7.56/modules/field/modules/text/text.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/modules/text/text.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ files[] = text.test required = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field/tests/field_test.info drupal-7.66/modules/field/tests/field_test.info --- drupal-7.56/modules/field/tests/field_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field/tests/field_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/field_ui/field_ui.info drupal-7.66/modules/field_ui/field_ui.info --- drupal-7.56/modules/field_ui/field_ui.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/field_ui/field_ui.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = field files[] = field_ui.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/file/file.field.inc drupal-7.66/modules/file/file.field.inc --- drupal-7.56/modules/file/file.field.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/file/file.field.inc 2019-04-17 22:20:46.000000000 +0200 @@ -599,7 +599,7 @@ // If the display field is present make sure its unchecked value is saved. $field = field_widget_field($element, $form_state); if (empty($input['display'])) { - $input['display'] = $field['settings']['display_field'] ? 0 : 1; + $input['display'] = !empty($field['settings']['display_field']) ? 0 : 1; } } diff -Naur drupal-7.56/modules/file/file.info drupal-7.66/modules/file/file.info --- drupal-7.56/modules/file/file.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/file/file.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = field files[] = tests/file.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/file/file.module drupal-7.66/modules/file/file.module --- drupal-7.56/modules/file/file.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/file/file.module 2019-04-17 22:20:46.000000000 +0200 @@ -140,7 +140,7 @@ } // Find out which (if any) fields of this type contain the file. - $references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type); + $references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, $field_type, FALSE); // Stop processing if there are no references in order to avoid returning // headers for files controlled by other modules. Make an exception for @@ -239,6 +239,9 @@ $form_parents = func_get_args(); $form_build_id = (string) array_pop($form_parents); + // Sanitize form parents before using them. + $form_parents = array_filter($form_parents, 'element_child'); + if (empty($_POST['form_build_id']) || $form_build_id != $_POST['form_build_id']) { // Invalid request. drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error'); @@ -1067,11 +1070,18 @@ * @param $field_type * (optional) The name of a field type. If given, limits the reference check * to fields of the given type. + * @param $check_access + * (optional) A boolean that specifies whether the permissions of the current + * user should be checked when retrieving references. If FALSE, all + * references to the file are returned. If TRUE, only references from + * entities that the current user has access to are returned. Defaults to + * TRUE for backwards compatibility reasons, but FALSE is recommended for + * most situations. * * @return * An integer value. */ -function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') { +function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file', $check_access = TRUE) { $references = drupal_static(__FUNCTION__, array()); $fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields(); @@ -1082,6 +1092,11 @@ $query ->fieldCondition($file_field, 'fid', $file->fid) ->age($age); + if (!$check_access) { + // Neutralize the 'entity_field_access' query tag added by + // field_sql_storage_field_storage_query(). + $query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); + } $references[$field_name] = $query->execute(); } } diff -Naur drupal-7.56/modules/file/tests/file.test drupal-7.66/modules/file/tests/file.test --- drupal-7.56/modules/file/tests/file.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/file/tests/file.test 2019-04-17 22:20:46.000000000 +0200 @@ -1626,6 +1626,79 @@ $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.'); } + + /** + * Tests file access for private nodes when file download access is granted. + */ + function testPrivateFileDownloadAccessGranted() { + // Tell file_module_test to attempt to grant access to all private files, + // and ensure that it is doing so correctly. + $test_file = $this->getTestFile('text'); + $uri = file_unmanaged_move($test_file->uri, 'private://'); + $file_url = file_create_url($uri); + $this->drupalGet($file_url); + $this->assertResponse(403, 'Access is not granted to an arbitrary private file by default.'); + variable_set('file_module_test_grant_download_access', TRUE); + $this->drupalGet($file_url); + $this->assertResponse(200, 'Access is granted to an arbitrary private file after a module grants access to all private files in hook_file_download().'); + + // Create a public node with a file attached. + $type_name = 'page'; + $field_name = strtolower($this->randomName()); + $this->createFileField($field_name, $type_name, array('uri_scheme' => 'private')); + $test_file = $this->getTestFile('text'); + $nid = $this->uploadNodeFile($test_file, $field_name, $type_name, TRUE, array('private' => FALSE)); + $node = node_load($nid, NULL, TRUE); + $file_url = file_create_url($node->{$field_name}[LANGUAGE_NONE][0]['uri']); + + // Unpublish the node and ensure that only administrators (not anonymous + // users) can access the node and download the file; the expectation is + // that the File module's hook_file_download() implementation will deny + // access and thereby override the file_module_test module's access grant. + $node->status = NODE_NOT_PUBLISHED; + node_save($node); + $this->drupalLogin($this->admin_user); + $this->drupalGet("node/$nid"); + $this->assertResponse(200, 'Administrator can access the unpublished node.'); + $this->drupalGet($file_url); + $this->assertResponse(200, 'Administrator can download the file attached to the unpublished node.'); + $this->drupalLogOut(); + $this->drupalGet("node/$nid"); + $this->assertResponse(403, 'Anonymous user cannot access the unpublished node.'); + $this->drupalGet($file_url); + $this->assertResponse(403, 'Anonymous user cannot download the file attached to the unpublished node.'); + + // Re-publish the node and ensure that the node and file can be accessed by + // everyone. + $node->status = NODE_PUBLISHED; + node_save($node); + $this->drupalLogin($this->admin_user); + $this->drupalGet("node/$nid"); + $this->assertResponse(200, 'Administrator can access the published node.'); + $this->drupalGet($file_url); + $this->assertResponse(200, 'Administrator can download the file attached to the published node.'); + $this->drupalLogOut(); + $this->drupalGet("node/$nid"); + $this->assertResponse(200, 'Anonymous user can access the published node.'); + $this->drupalGet($file_url); + $this->assertResponse(200, 'Anonymous user can download the file attached to the published node.'); + + // Make the node private via the node access system and test that only + // administrators (not anonymous users) can access the node and download + // the file. + $node->private = TRUE; + node_save($node); + $this->drupalLogin($this->admin_user); + $this->drupalGet("node/$nid"); + $this->assertResponse(200, 'Administrator can access the private node.'); + $this->drupalGet($file_url); + $this->assertResponse(200, 'Administrator can download the file attached to the private node.'); + $this->drupalLogOut(); + $this->drupalGet("node/$nid"); + $this->assertResponse(403, 'Anonymous user cannot access the private node.'); + $this->drupalGet($file_url); + $this->assertResponse(403, 'Anonymous user cannot download the file attached to the private node.'); + } } /** @@ -1802,3 +1875,60 @@ } } + +/** + * Tests the file_scan_directory() function. + */ +class FileScanDirectory extends FileFieldTestCase { + + /** + * @var string + */ + protected $path; + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'File ScanDirectory', + 'description' => 'Tests the file_scan_directory() function.', + 'group' => 'File', + ); + } + + /** + * {@inheritdoc} + */ + function setUp() { + parent::setUp(); + + $this->path = 'modules/file/tests/fixtures/file_scan_ignore'; + } + + /** + * Tests file_scan_directory() obeys 'file_scan_ignore_directories' setting. + * If nomask is not passed as argument, it should use the default settings. + * If nomask is passed as argument, it should obey this rule. + */ + public function testNoMask() { + $files = file_scan_directory($this->path, '/\.txt$/'); + $this->assertEqual(3, count($files), '3 text files found when not ignoring directories.'); + + global $conf; + $conf['file_scan_ignore_directories'] = array('frontend_framework'); + + $files = file_scan_directory($this->path, '/\.txt$/'); + $this->assertEqual(1, count($files), '1 text files found when ignoring directories called "frontend_framework".'); + + // Make that directories specified by default still work when a new nomask is provided. + $files = file_scan_directory($this->path, '/\.txt$/', array('nomask' => '/^c.txt/')); + $this->assertEqual(2, count($files), '2 text files found when an "nomask" option is passed in.'); + + // Ensure that the directories in file_scan_ignore_directories are escaped using preg_quote. + $conf['file_scan_ignore_directories'] = array('frontend.*'); + $files = file_scan_directory($this->path, '/\.txt$/'); + $this->assertEqual(3, count($files), '2 text files found when ignoring a directory that is not there.'); + } + +} diff -Naur drupal-7.56/modules/file/tests/file_module_test.info drupal-7.66/modules/file/tests/file_module_test.info --- drupal-7.56/modules/file/tests/file_module_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/file/tests/file_module_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/file/tests/file_module_test.module drupal-7.66/modules/file/tests/file_module_test.module --- drupal-7.56/modules/file/tests/file_module_test.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/file/tests/file_module_test.module 2019-04-17 22:20:46.000000000 +0200 @@ -67,3 +67,18 @@ } drupal_set_message(t('The file id is %fid.', array('%fid' => $fid))); } + +/** + * Implements hook_file_download(). + */ +function file_module_test_file_download($uri) { + if (variable_get('file_module_test_grant_download_access')) { + // Mimic what file_get_content_headers() would do if we had a full $file + // object to pass to it. + return array( + 'Content-Type' => mime_header_encode(file_get_mimetype($uri)), + 'Content-Length' => filesize($uri), + 'Cache-Control' => 'private', + ); + } +} diff -Naur drupal-7.56/modules/filter/filter.info drupal-7.66/modules/filter/filter.info --- drupal-7.56/modules/filter/filter.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/filter/filter.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ required = TRUE configure = admin/config/content/formats -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/forum/forum.info drupal-7.66/modules/forum/forum.info --- drupal-7.56/modules/forum/forum.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/forum/forum.info 2019-04-17 22:39:36.000000000 +0200 @@ -9,8 +9,7 @@ configure = admin/structure/forum stylesheets[all][] = forum.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/help/help.info drupal-7.66/modules/help/help.info --- drupal-7.56/modules/help/help.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/help/help.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = help.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/image/image.admin.inc drupal-7.66/modules/image/image.admin.inc --- drupal-7.56/modules/image/image.admin.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/image/image.admin.inc 2019-04-17 22:20:46.000000000 +0200 @@ -736,7 +736,8 @@ if (!isset($form[$key]['#access']) || $form[$key]['#access']) { $rows[] = array( 'data' => $row, - 'class' => !empty($form[$key]['weight']['#access']) || $key == 'new' ? array('draggable') : array(), + // Use a strict (===) comparison since $key can be 0. + 'class' => !empty($form[$key]['weight']['#access']) || $key === 'new' ? array('draggable') : array(), ); } } diff -Naur drupal-7.56/modules/image/image.info drupal-7.66/modules/image/image.info --- drupal-7.56/modules/image/image.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/image/image.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ files[] = image.test configure = admin/config/media/image-styles -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/image/tests/image_module_test.info drupal-7.66/modules/image/tests/image_module_test.info --- drupal-7.56/modules/image/tests/image_module_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/image/tests/image_module_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = image_module_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/locale/locale.info drupal-7.66/modules/locale/locale.info --- drupal-7.56/modules/locale/locale.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/locale/locale.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = locale.test configure = admin/config/regional/language -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/locale/locale.test drupal-7.66/modules/locale/locale.test --- drupal-7.56/modules/locale/locale.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/locale/locale.test 2019-04-17 22:20:46.000000000 +0200 @@ -3188,11 +3188,7 @@ foreach (language_types_info() as $type => $info) { if (isset($info['fixed'])) { $negotiation = variable_get("language_negotiation_$type", array()); - $equal = count($info['fixed']) == count($negotiation); - while ($equal && list($id) = each($negotiation)) { - list(, $info_id) = each($info['fixed']); - $equal = $info_id == $id; - } + $equal = array_keys($negotiation) === array_values($info['fixed']); $this->assertTrue($equal, format_string('language negotiation for %type is properly set up', array('%type' => $type))); } } diff -Naur drupal-7.56/modules/locale/tests/locale_test.info drupal-7.66/modules/locale/tests/locale_test.info --- drupal-7.56/modules/locale/tests/locale_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/locale/tests/locale_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/menu/menu.info drupal-7.66/modules/menu/menu.info --- drupal-7.56/modules/menu/menu.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/menu/menu.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = menu.test configure = admin/structure/menu -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/node/node.info drupal-7.66/modules/node/node.info --- drupal-7.56/modules/node/node.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/node/node.info 2019-04-17 22:39:36.000000000 +0200 @@ -9,8 +9,7 @@ configure = admin/structure/types stylesheets[all][] = node.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/node/tests/node_access_test.info drupal-7.66/modules/node/tests/node_access_test.info --- drupal-7.56/modules/node/tests/node_access_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/node/tests/node_access_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/node/tests/node_test.info drupal-7.66/modules/node/tests/node_test.info --- drupal-7.56/modules/node/tests/node_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/node/tests/node_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/node/tests/node_test_exception.info drupal-7.66/modules/node/tests/node_test_exception.info --- drupal-7.56/modules/node/tests/node_test_exception.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/node/tests/node_test_exception.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/openid/openid.info drupal-7.66/modules/openid/openid.info --- drupal-7.56/modules/openid/openid.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/openid/openid.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = openid.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/openid/tests/openid_test.info drupal-7.66/modules/openid/tests/openid_test.info --- drupal-7.56/modules/openid/tests/openid_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/openid/tests/openid_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = openid hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/overlay/overlay.info drupal-7.66/modules/overlay/overlay.info --- drupal-7.56/modules/overlay/overlay.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/overlay/overlay.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ version = VERSION core = 7.x -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/path/path.info drupal-7.66/modules/path/path.info --- drupal-7.56/modules/path/path.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/path/path.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = path.test configure = admin/config/search/path -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/path/path.test drupal-7.66/modules/path/path.test --- drupal-7.56/modules/path/path.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/path/path.test 2019-04-17 22:20:46.000000000 +0200 @@ -21,7 +21,7 @@ parent::setUp('path'); // Create test user and login. - $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases')); + $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases', 'access content overview')); $this->drupalLogin($web_user); } @@ -160,6 +160,34 @@ $this->drupalGet($edit['path[alias]']); $this->assertNoText($node1->title, 'Alias was successfully deleted.'); $this->assertResponse(404); + + // Create third test node. + $node3 = $this->drupalCreateNode(); + + // Create an invalid alias with a leading slash and verify that the slash + // is removed when the link is generated. This ensures that URL aliases + // cannot be used to inject external URLs. + // @todo The user interface should either display an error message or + // automatically trim these invalid aliases, rather than allowing them to + // be silently created, at which point the functional aspects of this + // test will need to be moved elsewhere and switch to using a + // programmatically-created alias instead. + $alias = $this->randomName(8); + $edit = array('path[alias]' => '/' . $alias); + $this->drupalPost('node/' . $node3->nid . '/edit', $edit, t('Save')); + $this->drupalGet('admin/content'); + // This checks the link href before clicking it, rather than using + // DrupalWebTestCase::assertUrl() after clicking it, because the test + // browser does not always preserve the correct number of slashes in the + // URL when it visits internal links; using DrupalWebTestCase::assertUrl() + // would actually make the test pass unconditionally on the testbot (or + // anywhere else where Drupal is installed in a subdirectory). + $link_xpath = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $node3->title)); + $link_href = (string) $link_xpath[0]['href']; + $link_prefix = base_path() . (variable_get('clean_url', 0) ? '' : '?q='); + $this->assertEqual($link_href, $link_prefix . $alias); + $this->clickLink($node3->title); + $this->assertResponse(404); } /** diff -Naur drupal-7.56/modules/php/php.info drupal-7.66/modules/php/php.info --- drupal-7.56/modules/php/php.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/php/php.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = php.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/poll/poll.info drupal-7.66/modules/poll/poll.info --- drupal-7.56/modules/poll/poll.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/poll/poll.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = poll.test stylesheets[all][] = poll.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/profile/profile.info drupal-7.66/modules/profile/profile.info --- drupal-7.56/modules/profile/profile.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/profile/profile.info 2019-04-17 22:39:36.000000000 +0200 @@ -11,8 +11,7 @@ ; See user_system_info_alter(). hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/rdf/rdf.info drupal-7.66/modules/rdf/rdf.info --- drupal-7.56/modules/rdf/rdf.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/rdf/rdf.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x files[] = rdf.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/rdf/tests/rdf_test.info drupal-7.66/modules/rdf/tests/rdf_test.info --- drupal-7.56/modules/rdf/tests/rdf_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/rdf/tests/rdf_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE dependencies[] = blog -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/search/search.info drupal-7.66/modules/search/search.info --- drupal-7.56/modules/search/search.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/search/search.info 2019-04-17 22:39:36.000000000 +0200 @@ -8,8 +8,7 @@ configure = admin/config/search/settings stylesheets[all][] = search.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/search/tests/search_embedded_form.info drupal-7.66/modules/search/tests/search_embedded_form.info --- drupal-7.56/modules/search/tests/search_embedded_form.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/search/tests/search_embedded_form.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/search/tests/search_extra_type.info drupal-7.66/modules/search/tests/search_extra_type.info --- drupal-7.56/modules/search/tests/search_extra_type.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/search/tests/search_extra_type.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/search/tests/search_node_tags.info drupal-7.66/modules/search/tests/search_node_tags.info --- drupal-7.56/modules/search/tests/search_node_tags.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/search/tests/search_node_tags.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/shortcut/shortcut.info drupal-7.66/modules/shortcut/shortcut.info --- drupal-7.56/modules/shortcut/shortcut.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/shortcut/shortcut.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = shortcut.test configure = admin/config/user-interface/shortcut -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/drupal_web_test_case.php drupal-7.66/modules/simpletest/drupal_web_test_case.php --- drupal-7.56/modules/simpletest/drupal_web_test_case.php 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/drupal_web_test_case.php 2019-04-17 22:20:46.000000000 +0200 @@ -3012,7 +3012,7 @@ if (!$message) { $message = t('Raw "@raw" found', array('@raw' => $raw)); } - return $this->assert(strpos($this->drupalGetContent(), $raw) !== FALSE, $message, $group); + return $this->assert(strpos($this->drupalGetContent(), (string) $raw) !== FALSE, $message, $group); } /** @@ -3032,7 +3032,7 @@ if (!$message) { $message = t('Raw "@raw" not found', array('@raw' => $raw)); } - return $this->assert(strpos($this->drupalGetContent(), $raw) === FALSE, $message, $group); + return $this->assert(strpos($this->drupalGetContent(), (string) $raw) === FALSE, $message, $group); } /** diff -Naur drupal-7.56/modules/simpletest/files/phar-1.phar drupal-7.66/modules/simpletest/files/phar-1.phar --- drupal-7.56/modules/simpletest/files/phar-1.phar 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/modules/simpletest/files/phar-1.phar 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,301 @@ + 2, +'c' => 'text/plain', +'cc' => 'text/plain', +'cpp' => 'text/plain', +'c++' => 'text/plain', +'dtd' => 'text/plain', +'h' => 'text/plain', +'log' => 'text/plain', +'rng' => 'text/plain', +'txt' => 'text/plain', +'xsd' => 'text/plain', +'php' => 1, +'inc' => 1, +'avi' => 'video/avi', +'bmp' => 'image/bmp', +'css' => 'text/css', +'gif' => 'image/gif', +'htm' => 'text/html', +'html' => 'text/html', +'htmls' => 'text/html', +'ico' => 'image/x-ico', +'jpe' => 'image/jpeg', +'jpg' => 'image/jpeg', +'jpeg' => 'image/jpeg', +'js' => 'application/x-javascript', +'midi' => 'audio/midi', +'mid' => 'audio/midi', +'mod' => 'audio/mod', +'mov' => 'movie/quicktime', +'mp3' => 'audio/mp3', +'mpg' => 'video/mpeg', +'mpeg' => 'video/mpeg', +'pdf' => 'application/pdf', +'png' => 'image/png', +'swf' => 'application/shockwave-flash', +'tif' => 'image/tiff', +'tiff' => 'image/tiff', +'wav' => 'audio/wav', +'xbm' => 'image/xbm', +'xml' => 'text/xml', +); + +header("Cache-Control: no-cache, must-revalidate"); +header("Pragma: no-cache"); + +$basename = basename(__FILE__); +if (!strpos($_SERVER['REQUEST_URI'], $basename)) { +chdir(Extract_Phar::$temp); +include $web; +return; +} +$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename)); +if (!$pt || $pt == '/') { +$pt = $web; +header('HTTP/1.1 301 Moved Permanently'); +header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt); +exit; +} +$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt); +if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) { +header('HTTP/1.0 404 Not Found'); +echo "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +exit; +} +$b = pathinfo($a); +if (!isset($b['extension'])) { +header('Content-Type: text/plain'); +header('Content-Length: ' . filesize($a)); +readfile($a); +exit; +} +if (isset($mimes[$b['extension']])) { +if ($mimes[$b['extension']] === 1) { +include $a; +exit; +} +if ($mimes[$b['extension']] === 2) { +highlight_file($a); +exit; +} +header('Content-Type: ' .$mimes[$b['extension']]); +header('Content-Length: ' . filesize($a)); +readfile($a); +exit; +} +} + +class Extract_Phar +{ +static $temp; +static $origdir; +const GZ = 0x1000; +const BZ2 = 0x2000; +const MASK = 0x3000; +const START = 'index.php'; +const LEN = 6643; + +static function go($return = false) +{ +$fp = fopen(__FILE__, 'rb'); +fseek($fp, self::LEN); +$L = unpack('V', $a = fread($fp, 4)); +$m = ''; + +do { +$read = 8192; +if ($L[1] - strlen($m) < 8192) { +$read = $L[1] - strlen($m); +} +$last = fread($fp, $read); +$m .= $last; +} while (strlen($last) && strlen($m) < $L[1]); + +if (strlen($m) < $L[1]) { +die('ERROR: manifest length read was "' . +strlen($m) .'" should be "' . +$L[1] . '"'); +} + +$info = self::_unpack($m); +$f = $info['c']; + +if ($f & self::GZ) { +if (!function_exists('gzinflate')) { +die('Error: zlib extension is not enabled -' . +' gzinflate() function needed for zlib-compressed .phars'); +} +} + +if ($f & self::BZ2) { +if (!function_exists('bzdecompress')) { +die('Error: bzip2 extension is not enabled -' . +' bzdecompress() function needed for bz2-compressed .phars'); +} +} + +$temp = self::tmpdir(); + +if (!$temp || !is_writable($temp)) { +$sessionpath = session_save_path(); +if (strpos ($sessionpath, ";") !== false) +$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1); +if (!file_exists($sessionpath) || !is_dir($sessionpath)) { +die('Could not locate temporary directory to extract phar'); +} +$temp = $sessionpath; +} + +$temp .= '/pharextract/'.basename(__FILE__, '.phar'); +self::$temp = $temp; +self::$origdir = getcwd(); +@mkdir($temp, 0777, true); +$temp = realpath($temp); + +if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) { +self::_removeTmpFiles($temp, getcwd()); +@mkdir($temp, 0777, true); +@file_put_contents($temp . '/' . md5_file(__FILE__), ''); + +foreach ($info['m'] as $path => $file) { +$a = !file_exists(dirname($temp . '/' . $path)); +@mkdir(dirname($temp . '/' . $path), 0777, true); +clearstatcache(); + +if ($path[strlen($path) - 1] == '/') { +@mkdir($temp . '/' . $path, 0777); +} else { +file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp)); +@chmod($temp . '/' . $path, 0666); +} +} +} + +chdir($temp); + +if (!$return) { +include self::START; +} +} + +static function tmpdir() +{ +if (strpos(PHP_OS, 'WIN') !== false) { +if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) { +return $var; +} +if (is_dir('/temp') || mkdir('/temp')) { +return realpath('/temp'); +} +return false; +} +if ($var = getenv('TMPDIR')) { +return $var; +} +return realpath('/tmp'); +} + +static function _unpack($m) +{ +$info = unpack('V', substr($m, 0, 4)); + $l = unpack('V', substr($m, 10, 4)); +$m = substr($m, 14 + $l[1]); +$s = unpack('V', substr($m, 0, 4)); +$o = 0; +$start = 4 + $s[1]; +$ret['c'] = 0; + +for ($i = 0; $i < $info[1]; $i++) { + $len = unpack('V', substr($m, $start, 4)); +$start += 4; + $savepath = substr($m, $start, $len[1]); +$start += $len[1]; + $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); +$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] +& 0xffffffff); +$ret['m'][$savepath][7] = $o; +$o += $ret['m'][$savepath][2]; +$start += 24 + $ret['m'][$savepath][5]; +$ret['c'] |= $ret['m'][$savepath][4] & self::MASK; +} +return $ret; +} + +static function extractFile($path, $entry, $fp) +{ +$data = ''; +$c = $entry[2]; + +while ($c) { +if ($c < 8192) { +$data .= @fread($fp, $c); +$c = 0; +} else { +$c -= 8192; +$data .= @fread($fp, 8192); +} +} + +if ($entry[4] & self::GZ) { +$data = gzinflate($data); +} elseif ($entry[4] & self::BZ2) { +$data = bzdecompress($data); +} + +if (strlen($data) != $entry[0]) { +die("Invalid internal .phar file (size error " . strlen($data) . " != " . +$stat[7] . ")"); +} + +if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { +die("Invalid internal .phar file (checksum error)"); +} + +return $data; +} + +static function _removeTmpFiles($temp, $origdir) +{ +chdir($temp); + +foreach (glob('*') as $f) { +if (file_exists($f)) { +is_dir($f) ? @rmdir($f) : @unlink($f); +if (file_exists($f) && is_dir($f)) { +self::_removeTmpFiles($f, getcwd()); +} +} +} + +@rmdir($temp); +clearstatcache(); +chdir($origdir); +} +} + +Extract_Phar::go(); +__HALT_COMPILER(); ?>7������������������ ���index.phpµ���8!¾[µ���u‰¾¶������<?php +/** + * @file + * This test file is used to test Drupal's phar stream wrapper functionality. + * + * @see \Drupal\KernelTests\Core\File\PharWrapperTest + */ + +echo 'Hello, world!'; +å1qV«5õ['áyß R£CØA���GBMB \ No newline at end of file diff -Naur drupal-7.56/modules/simpletest/simpletest.info drupal-7.66/modules/simpletest/simpletest.info --- drupal-7.56/modules/simpletest/simpletest.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/simpletest.info 2019-04-17 22:39:36.000000000 +0200 @@ -57,8 +57,7 @@ files[] = tests/upgrade/update.field.test files[] = tests/upgrade/update.user.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/actions_loop_test.info drupal-7.66/modules/simpletest/tests/actions_loop_test.info --- drupal-7.56/modules/simpletest/tests/actions_loop_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/actions_loop_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/ajax_forms_test.info drupal-7.66/modules/simpletest/tests/ajax_forms_test.info --- drupal-7.56/modules/simpletest/tests/ajax_forms_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/ajax_forms_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/ajax_test.info drupal-7.66/modules/simpletest/tests/ajax_test.info --- drupal-7.56/modules/simpletest/tests/ajax_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/ajax_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/batch_test.info drupal-7.66/modules/simpletest/tests/batch_test.info --- drupal-7.56/modules/simpletest/tests/batch_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/batch_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/boot_test_1.info drupal-7.66/modules/simpletest/tests/boot_test_1.info --- drupal-7.56/modules/simpletest/tests/boot_test_1.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/boot_test_1.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/boot_test_2.info drupal-7.66/modules/simpletest/tests/boot_test_2.info --- drupal-7.56/modules/simpletest/tests/boot_test_2.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/boot_test_2.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/bootstrap.test drupal-7.66/modules/simpletest/tests/bootstrap.test --- drupal-7.56/modules/simpletest/tests/bootstrap.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/bootstrap.test 2019-04-17 22:20:46.000000000 +0200 @@ -729,16 +729,12 @@ * Tests that the drupal_check_memory_limit() function works as expected. */ function testCheckMemoryLimit() { - $memory_limit = ini_get('memory_limit'); // Test that a very reasonable amount of memory is available. $this->assertTrue(drupal_check_memory_limit('30MB'), '30MB of memory tested available.'); - // Get the available memory and multiply it by two to make it unreasonably - // high. - $twice_avail_memory = ($memory_limit * 2) . 'MB'; - + // Test an unlimited memory limit. // The function should always return true if the memory limit is set to -1. - $this->assertTrue(drupal_check_memory_limit($twice_avail_memory, -1), 'drupal_check_memory_limit() returns TRUE when a limit of -1 (none) is supplied'); + $this->assertTrue(drupal_check_memory_limit('9999999999YB', -1), 'drupal_check_memory_limit() returns TRUE when a limit of -1 (none) is supplied'); // Test that even though we have 30MB of memory available - the function // returns FALSE when given an upper limit for how much memory can be used. diff -Naur drupal-7.56/modules/simpletest/tests/common.test drupal-7.66/modules/simpletest/tests/common.test --- drupal-7.56/modules/simpletest/tests/common.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/common.test 2019-04-17 22:20:46.000000000 +0200 @@ -76,7 +76,7 @@ class CommonURLUnitTest extends DrupalWebTestCase { public static function getInfo() { return array( - 'name' => 'URL generation tests', + 'name' => 'URL generation unit tests', 'description' => 'Confirm that url(), drupal_get_query_parameters(), drupal_http_build_query(), and l() work correctly with various input.', 'group' => 'System', ); @@ -373,6 +373,38 @@ } /** + * Web tests for URL generation functions. + */ +class CommonURLWebTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'URL generation web tests', + 'description' => 'Confirm that URL-generating functions work correctly on specific site paths.', + 'group' => 'System', + ); + } + + function setUp() { + parent::setUp('common_test'); + } + + /** + * Tests the url() function on internal paths which mimic external URLs. + */ + function testInternalPathMimicsExternal() { + // Ensure that calling url(current_path()) on "/http://example.com" (an + // internal path which mimics an external URL) always links to the internal + // path, not the external URL. This helps protect against external URL link + // injection vulnerabilities. + variable_set('common_test_link_to_current_path', TRUE); + $this->drupalGet('/http://example.com'); + $this->clickLink('link which should point to the current path'); + $this->assertUrl('/http://example.com'); + $this->assertText('link which should point to the current path'); + } +} + +/** * Tests url_is_external(). */ class UrlIsExternalUnitTest extends DrupalUnitTestCase { diff -Naur drupal-7.56/modules/simpletest/tests/common_test.info drupal-7.66/modules/simpletest/tests/common_test.info --- drupal-7.56/modules/simpletest/tests/common_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/common_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ stylesheets[print][] = common_test.print.css hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/common_test.module drupal-7.66/modules/simpletest/tests/common_test.module --- drupal-7.56/modules/simpletest/tests/common_test.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/common_test.module 2019-04-17 22:20:46.000000000 +0200 @@ -99,6 +99,9 @@ if (variable_get('common_test_redirect_current_path', FALSE)) { drupal_goto(current_path()); } + if (variable_get('common_test_link_to_current_path', FALSE)) { + drupal_set_message(l('link which should point to the current path', current_path())); + } } /** diff -Naur drupal-7.56/modules/simpletest/tests/common_test_cron_helper.info drupal-7.66/modules/simpletest/tests/common_test_cron_helper.info --- drupal-7.56/modules/simpletest/tests/common_test_cron_helper.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/common_test_cron_helper.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/database_test.info drupal-7.66/modules/simpletest/tests/database_test.info --- drupal-7.56/modules/simpletest/tests/database_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/database_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info drupal-7.66/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info --- drupal-7.56/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info drupal-7.66/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info --- drupal-7.56/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info drupal-7.66/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info --- drupal-7.56/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/entity_cache_test.info drupal-7.66/modules/simpletest/tests/entity_cache_test.info --- drupal-7.56/modules/simpletest/tests/entity_cache_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/entity_cache_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ dependencies[] = entity_cache_test_dependency hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/entity_cache_test_dependency.info drupal-7.66/modules/simpletest/tests/entity_cache_test_dependency.info --- drupal-7.56/modules/simpletest/tests/entity_cache_test_dependency.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/entity_cache_test_dependency.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/entity_crud_hook_test.info drupal-7.66/modules/simpletest/tests/entity_crud_hook_test.info --- drupal-7.56/modules/simpletest/tests/entity_crud_hook_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/entity_crud_hook_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/entity_query_access_test.info drupal-7.66/modules/simpletest/tests/entity_query_access_test.info --- drupal-7.56/modules/simpletest/tests/entity_query_access_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/entity_query_access_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/error_test.info drupal-7.66/modules/simpletest/tests/error_test.info --- drupal-7.56/modules/simpletest/tests/error_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/error_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/file.test drupal-7.66/modules/simpletest/tests/file.test --- drupal-7.56/modules/simpletest/tests/file.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/file.test 2019-04-17 22:20:46.000000000 +0200 @@ -957,6 +957,15 @@ $path = file_create_filename($basename, $directory); $this->assertEqual($path, $expected, format_string('Creating a new filepath from %original equals %new.', array('%new' => $path, '%original' => $original)), 'File'); + try { + $filename = "a\xFFtest\x80€.txt"; + file_create_filename($filename, $directory); + $this->fail('Expected exception not thrown'); + } + catch (RuntimeException $e) { + $this->assertEqual("Invalid filename '$filename'", $e->getMessage()); + } + // @TODO: Finally we copy a file into a directory several times, to ensure a properly iterating filename suffix. } @@ -989,6 +998,14 @@ $this->assertNotEqual($path, $destination, 'A new filepath destination is created when filepath destination already exists with FILE_EXISTS_RENAME.', 'File'); $path = file_destination($destination, FILE_EXISTS_ERROR); $this->assertEqual($path, FALSE, 'An error is returned when filepath destination already exists with FILE_EXISTS_ERROR.', 'File'); + + try { + file_destination("core/misc/a\xFFtest\x80€.txt", FILE_EXISTS_REPLACE); + $this->fail('Expected exception not thrown'); + } + catch (RuntimeException $e) { + $this->assertEqual("Invalid filename 'a\xFFtest\x80€.txt'", $e->getMessage()); + } } /** @@ -2766,4 +2783,64 @@ $this->assertTrue(file_stream_wrapper_valid_scheme(file_uri_scheme('public://asdf')), 'Got a valid stream scheme from public://asdf'); $this->assertFalse(file_stream_wrapper_valid_scheme(file_uri_scheme('foo://asdf')), 'Did not get a valid stream scheme from foo://asdf'); } + + /** + * Tests that phar stream wrapper is registered as expected. + * + * @see file_get_stream_wrappers() + */ + public function testPharStreamWrapperRegistration() { + if (!class_exists('Phar', FALSE)) { + $this->assertFalse(in_array('phar', stream_get_wrappers(), TRUE), 'PHP is compiled without phar support. Therefore, no phar stream wrapper is registered.'); + } + elseif (version_compare(PHP_VERSION, '5.3.3', '<')) { + $this->assertFalse(in_array('phar', stream_get_wrappers(), TRUE), 'The PHP version is <5.3.3. The built-in phar stream wrapper has been unregistered and not replaced.'); + } + else { + $this->assertTrue(in_array('phar', stream_get_wrappers(), TRUE), 'A phar stream wrapper is registered.'); + $this->assertFalse(file_stream_wrapper_valid_scheme('phar'), 'The phar scheme is not a valid scheme for Drupal File API usage.'); + } + + // Ensure that calling file_get_stream_wrappers() multiple times, both + // without and with a drupal_static_reset() in between, does not create + // errors due to the PharStreamWrapperManager singleton. + file_get_stream_wrappers(); + file_get_stream_wrappers(); + drupal_static_reset('file_get_stream_wrappers'); + file_get_stream_wrappers(); + } + + /** + * Tests that only valid phar files can be used. + */ + public function testPharFile() { + if (!in_array('phar', stream_get_wrappers(), TRUE)) { + $this->pass('There is no phar stream wrapper registered.'); + // Nothing else in this test is relevant when there's no phar stream + // wrapper. testPharStreamWrapperRegistration() is sufficient for testing + // the conditions of when the stream wrapper should or should not be + // registered. + return; + } + + $base = dirname(dirname(__FILE__)) . '/files'; + + // Ensure that file operations via the phar:// stream wrapper work for phar + // files with the .phar extension. + $this->assertFalse(file_exists("phar://$base/phar-1.phar/no-such-file.php")); + $this->assertTrue(file_exists("phar://$base/phar-1.phar/index.php")); + $file_contents = file_get_contents("phar://$base/phar-1.phar/index.php"); + $expected_hash = 'c7e7904ea573c5ebea3ef00bb08c1f86af1a45961fbfbeb1892ff4a98fd73ad5'; + $this->assertIdentical($expected_hash, hash('sha256', $file_contents)); + + // Ensure that file operations via the phar:// stream wrapper throw an + // exception for files without the .phar extension. + try { + file_exists("phar://$base/image-2.jpg/index.php"); + $this->fail('Expected exception failed to be thrown when accessing an invalid phar file.'); + } + catch (Exception $e) { + $this->assertEqual(get_class($e), 'TYPO3\PharStreamWrapper\Exception', 'Expected exception thrown when accessing an invalid phar file.'); + } + } } diff -Naur drupal-7.56/modules/simpletest/tests/file_test.info drupal-7.66/modules/simpletest/tests/file_test.info --- drupal-7.56/modules/simpletest/tests/file_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/file_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = file_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/filter_test.info drupal-7.66/modules/simpletest/tests/filter_test.info --- drupal-7.56/modules/simpletest/tests/filter_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/filter_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/form.test drupal-7.66/modules/simpletest/tests/form.test --- drupal-7.56/modules/simpletest/tests/form.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/form.test 2019-04-17 22:20:46.000000000 +0200 @@ -1421,6 +1421,59 @@ } /** + * Test cache_form. + */ +class FormsFormCacheTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Form caching', + 'description' => 'Tests storage and retrieval of forms from cache.', + 'group' => 'Form API', + ); + } + + function setUp() { + parent::setUp('form_test'); + } + + /** + * Tests storing and retrieving the form from cache. + */ + function testCacheForm() { + $form = drupal_get_form('form_test_cache_form'); + $form_state = array('foo' => 'bar', 'build_info' => array('baz')); + form_set_cache($form['#build_id'], $form, $form_state); + + $cached_form_state = array(); + $cached_form = form_get_cache($form['#build_id'], $cached_form_state); + + $this->assertEqual($cached_form['#build_id'], $form['#build_id'], 'Form retrieved from cache_form successfully.'); + $this->assertEqual($cached_form_state['foo'], 'bar', 'Data retrieved from cache_form successfully.'); + } + + /** + * Tests changing form_cache_expiration. + */ + function testCacheFormCustomExpiration() { + variable_set('form_cache_expiration', -1 * (24 * 60 * 60)); + + $form = drupal_get_form('form_test_cache_form'); + $form_state = array('foo' => 'bar', 'build_info' => array('baz')); + form_set_cache($form['#build_id'], $form, $form_state); + + // Clear expired entries from cache_form, which should include the entry we + // just stored. Without this, the form will still be retrieved from cache. + cache_clear_all(NULL, 'cache_form'); + + $cached_form_state = array(); + $cached_form = form_get_cache($form['#build_id'], $cached_form_state); + + $this->assertNull($cached_form, 'Expired form was not returned from cache.'); + $this->assertTrue(empty($cached_form_state), 'No data retrieved from cache for expired form.'); + } +} + +/** * Test wrapper form callbacks. */ class FormsFormWrapperTestCase extends DrupalWebTestCase { diff -Naur drupal-7.56/modules/simpletest/tests/form_test.info drupal-7.66/modules/simpletest/tests/form_test.info --- drupal-7.56/modules/simpletest/tests/form_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/form_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/form_test.module drupal-7.66/modules/simpletest/tests/form_test.module --- drupal-7.56/modules/simpletest/tests/form_test.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/form_test.module 2019-04-17 22:20:46.000000000 +0200 @@ -919,6 +919,24 @@ } /** + * A simple form for testing form caching. + */ +function form_test_cache_form($form, &$form_state) { + $form['title'] = array( + '#type' => 'textfield', + '#title' => 'Title', + '#required' => TRUE, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + + return $form; +} + +/** * A form for testing form labels and required marks. */ function form_label_test_form() { diff -Naur drupal-7.56/modules/simpletest/tests/image.test drupal-7.66/modules/simpletest/tests/image.test --- drupal-7.56/modules/simpletest/tests/image.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/image.test 2019-04-17 22:20:46.000000000 +0200 @@ -335,7 +335,9 @@ ); // Systems using non-bundled GD2 don't have imagerotate. Test if available. - if (function_exists('imagerotate')) { + // @todo Remove the version check once https://www.drupal.org/node/2918570 + // is resolved. + if (function_exists('imagerotate') && (version_compare(PHP_VERSION, '7.0.26', '<') || (version_compare(PHP_VERSION, '7.1', '>=') && version_compare(PHP_VERSION, '7.1.12', '<')))) { $operations += array( 'rotate_90' => array( 'function' => 'rotate', @@ -357,8 +359,8 @@ // See https://bugs.php.net/bug.php?id=65148. // For the 40x20 test images, the dimensions resulting from rotation will // be 1 pixel smaller in both width and height in PHP 5.5 and above. - // @todo: If and when the PHP bug gets solved, add an upper limit - // version check. + // @todo: The PHP bug was fixed in PHP 7.0.26 and 7.1.12. Change the code + // below to reflect that in https://www.drupal.org/node/2918570. if (version_compare(PHP_VERSION, '5.5', '>=')) { $operations += array( 'rotate_5' => array( diff -Naur drupal-7.56/modules/simpletest/tests/image_test.info drupal-7.66/modules/simpletest/tests/image_test.info --- drupal-7.56/modules/simpletest/tests/image_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/image_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/menu_test.info drupal-7.66/modules/simpletest/tests/menu_test.info --- drupal-7.56/modules/simpletest/tests/menu_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/menu_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/module_test.info drupal-7.66/modules/simpletest/tests/module_test.info --- drupal-7.56/modules/simpletest/tests/module_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/module_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/path_test.info drupal-7.66/modules/simpletest/tests/path_test.info --- drupal-7.56/modules/simpletest/tests/path_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/path_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/psr_0_test/psr_0_test.info drupal-7.66/modules/simpletest/tests/psr_0_test/psr_0_test.info --- drupal-7.56/modules/simpletest/tests/psr_0_test/psr_0_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/psr_0_test/psr_0_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ hidden = TRUE package = Testing -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/psr_4_test/psr_4_test.info drupal-7.66/modules/simpletest/tests/psr_4_test/psr_4_test.info --- drupal-7.56/modules/simpletest/tests/psr_4_test/psr_4_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/psr_4_test/psr_4_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ hidden = TRUE package = Testing -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/requirements1_test.info drupal-7.66/modules/simpletest/tests/requirements1_test.info --- drupal-7.56/modules/simpletest/tests/requirements1_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/requirements1_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/requirements2_test.info drupal-7.66/modules/simpletest/tests/requirements2_test.info --- drupal-7.56/modules/simpletest/tests/requirements2_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/requirements2_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/session_test.info drupal-7.66/modules/simpletest/tests/session_test.info --- drupal-7.56/modules/simpletest/tests/session_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/session_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_dependencies_test.info drupal-7.66/modules/simpletest/tests/system_dependencies_test.info --- drupal-7.56/modules/simpletest/tests/system_dependencies_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_dependencies_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE dependencies[] = _missing_dependency -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info drupal-7.66/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info --- drupal-7.56/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE dependencies[] = system_incompatible_core_version_test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_incompatible_core_version_test.info drupal-7.66/modules/simpletest/tests/system_incompatible_core_version_test.info --- drupal-7.56/modules/simpletest/tests/system_incompatible_core_version_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_incompatible_core_version_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 5.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info drupal-7.66/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info --- drupal-7.56/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ ; system_incompatible_module_version_test declares version 1.0 dependencies[] = system_incompatible_module_version_test (>2.0) -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_incompatible_module_version_test.info drupal-7.66/modules/simpletest/tests/system_incompatible_module_version_test.info --- drupal-7.56/modules/simpletest/tests/system_incompatible_module_version_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_incompatible_module_version_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_project_namespace_test.info drupal-7.66/modules/simpletest/tests/system_project_namespace_test.info --- drupal-7.56/modules/simpletest/tests/system_project_namespace_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_project_namespace_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE dependencies[] = drupal:filter -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/system_test.info drupal-7.66/modules/simpletest/tests/system_test.info --- drupal-7.56/modules/simpletest/tests/system_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/system_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = system_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/taxonomy_test.info drupal-7.66/modules/simpletest/tests/taxonomy_test.info --- drupal-7.56/modules/simpletest/tests/taxonomy_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/taxonomy_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE dependencies[] = taxonomy -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/theme_test.info drupal-7.66/modules/simpletest/tests/theme_test.info --- drupal-7.56/modules/simpletest/tests/theme_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/theme_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info drupal-7.66/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info --- drupal-7.56/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ settings[basetheme_only] = base theme value settings[subtheme_override] = base theme value -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info drupal-7.66/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info --- drupal-7.56/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ settings[subtheme_override] = subtheme value -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/themes/test_theme/test_theme.info drupal-7.66/modules/simpletest/tests/themes/test_theme/test_theme.info --- drupal-7.56/modules/simpletest/tests/themes/test_theme/test_theme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/themes/test_theme/test_theme.info 2019-04-17 22:39:36.000000000 +0200 @@ -17,8 +17,7 @@ settings[theme_test_setting] = default value -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/themes/test_theme/theme-settings.php drupal-7.66/modules/simpletest/tests/themes/test_theme/theme-settings.php --- drupal-7.56/modules/simpletest/tests/themes/test_theme/theme-settings.php 1970-01-01 01:00:00.000000000 +0100 +++ drupal-7.66/modules/simpletest/tests/themes/test_theme/theme-settings.php 2019-04-17 22:20:46.000000000 +0200 @@ -0,0 +1,32 @@ +<?php + +/** + * @file + * Theme setting callbacks for the test_theme theme. + */ + +/** + * Implements hook_form_FORM_ID_alter(). + */ +function test_theme_form_system_theme_settings_alter(&$form, &$form_state) { + $form['test_theme_checkbox'] = array( + '#type' => 'checkbox', + '#title' => 'Test theme checkbox', + '#default_value' => theme_get_setting('test_theme_checkbox'), + ); + + // Force the form to be cached so we can test that this file is properly + // loaded and the custom submit handler is properly called even on a cached + // form build. + $form_state['cache'] = TRUE; + $form['#submit'][] = 'test_theme_form_system_theme_settings_submit'; +} + +/** + * Form submission handler for the test theme settings form. + * + * @see test_theme_form_system_theme_settings_alter() + */ +function test_theme_form_system_theme_settings_submit($form, &$form_state) { + drupal_set_message('The test theme setting was saved.'); +} diff -Naur drupal-7.56/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info drupal-7.66/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info --- drupal-7.56/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ hidden = TRUE engine = nyan_cat -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/update_script_test.info drupal-7.66/modules/simpletest/tests/update_script_test.info --- drupal-7.56/modules/simpletest/tests/update_script_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/update_script_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/update_test_1.info drupal-7.66/modules/simpletest/tests/update_test_1.info --- drupal-7.56/modules/simpletest/tests/update_test_1.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/update_test_1.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/update_test_2.info drupal-7.66/modules/simpletest/tests/update_test_2.info --- drupal-7.56/modules/simpletest/tests/update_test_2.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/update_test_2.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/update_test_3.info drupal-7.66/modules/simpletest/tests/update_test_3.info --- drupal-7.56/modules/simpletest/tests/update_test_3.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/update_test_3.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/url_alter_test.info drupal-7.66/modules/simpletest/tests/url_alter_test.info --- drupal-7.56/modules/simpletest/tests/url_alter_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/url_alter_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/simpletest/tests/xmlrpc_test.info drupal-7.66/modules/simpletest/tests/xmlrpc_test.info --- drupal-7.56/modules/simpletest/tests/xmlrpc_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/simpletest/tests/xmlrpc_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/statistics/statistics.info drupal-7.66/modules/statistics/statistics.info --- drupal-7.56/modules/statistics/statistics.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/statistics/statistics.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = statistics.test configure = admin/config/system/statistics -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/syslog/syslog.info drupal-7.66/modules/syslog/syslog.info --- drupal-7.56/modules/syslog/syslog.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/syslog/syslog.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = syslog.test configure = admin/config/development/logging -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/system/system.admin.inc drupal-7.66/modules/system/system.admin.inc --- drupal-7.56/modules/system/system.admin.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.admin.inc 2019-04-17 22:20:46.000000000 +0200 @@ -572,9 +572,10 @@ // Process the theme and all its base themes. foreach ($theme_keys as $theme) { // Include the theme-settings.php file. - $filename = DRUPAL_ROOT . '/' . str_replace("/$theme.info", '', $themes[$theme]->filename) . '/theme-settings.php'; - if (file_exists($filename)) { - require_once $filename; + $theme_settings_path = drupal_get_path('theme', $theme) . '/theme-settings.php'; + if (file_exists(DRUPAL_ROOT . '/' . $theme_settings_path)) { + require_once DRUPAL_ROOT . '/' . $theme_settings_path; + $form_state['build_info']['files'][] = $theme_settings_path; } // Call theme-specific settings. @@ -1812,7 +1813,7 @@ '#title' => t('Private file system path'), '#default_value' => variable_get('file_private_path', ''), '#maxlength' => 255, - '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'http://drupal.org/documentation/modules/file')), + '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'https://www.drupal.org/docs/7/core/modules/file/overview')), '#after_build' => array('system_check_directory'), ); @@ -2565,9 +2566,21 @@ /** * Returns HTML for the status report. * + * This theme function is dependent on install.inc being loaded, because + * that's where the constants are defined. + * * @param $variables * An associative array containing: - * - requirements: An array of requirements. + * - requirements: An array of requirements/status items. Each requirement + * is an associative array containing the following elements: + * - title: The name of the requirement. + * - value: (optional) The current value (version, time, level, etc). + * - description: (optional) The description of the requirement. + * - severity: (optional) The requirement's result/severity level, one of: + * - REQUIREMENT_INFO: Status information. + * - REQUIREMENT_OK: The requirement is satisfied. + * - REQUIREMENT_WARNING: The requirement failed with a warning. + * - REQUIREMENT_ERROR: The requirement failed with an error. * * @ingroup themeable */ diff -Naur drupal-7.56/modules/system/system.api.php drupal-7.66/modules/system/system.api.php --- drupal-7.56/modules/system/system.api.php 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.api.php 2019-04-17 22:20:46.000000000 +0200 @@ -1888,8 +1888,8 @@ * * This hook is not run on cached pages. * - * To add CSS or JS that should be present on all pages, modules should not - * implement this hook, but declare these files in their .info file. + * To add CSS or JS files that should be present on all pages, modules should + * not implement this hook, but declare these files in their .info file. * * @see hook_boot() */ diff -Naur drupal-7.56/modules/system/system.info drupal-7.66/modules/system/system.info --- drupal-7.56/modules/system/system.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/system/system.info 2019-04-17 22:39:36.000000000 +0200 @@ -12,8 +12,7 @@ required = TRUE configure = admin/config/system -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/system/system.install drupal-7.66/modules/system/system.install --- drupal-7.56/modules/system/system.install 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.install 2019-04-17 22:20:46.000000000 +0200 @@ -2870,7 +2870,7 @@ if (!db_table_exists('system_update_7061')) { $table = array( 'description' => t('Stores temporary data for system_update_7061.'), - 'fields' => array('vid' => array('type' => 'int')), + 'fields' => array('vid' => array('type' => 'int', 'not null' => TRUE)), 'primary key' => array('vid'), ); db_create_table('system_update_7061', $table); @@ -3286,6 +3286,13 @@ } /** + * Add 'jquery-extend-3.4.0.js' to the 'jquery' library. + */ +function system_update_7082() { + // Empty update to force a rebuild of hook_library() and JS aggregates. +} + +/** * @} End of "defgroup updates-7.x-extra". * The next series of updates should start at 8000. */ diff -Naur drupal-7.56/modules/system/system.mail.inc drupal-7.66/modules/system/system.mail.inc --- drupal-7.56/modules/system/system.mail.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.mail.inc 2019-04-17 22:20:46.000000000 +0200 @@ -70,7 +70,9 @@ // hosts. The return value of this method will still indicate whether mail // was sent successfully. if (!isset($_SERVER['WINDIR']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') === FALSE) { - if (isset($message['Return-Path']) && !ini_get('safe_mode')) { + // We validate the return path, unless it is equal to the site mail, which + // we assume to be safe. + if (isset($message['Return-Path']) && !ini_get('safe_mode') && (variable_get('site_mail', ini_get('sendmail_from')) === $message['Return-Path'] || self::_isShellSafe($message['Return-Path']))) { // On most non-Windows systems, the "-f" option to the sendmail command // is used to set the Return-Path. There is no space between -f and // the value of the return path. @@ -109,6 +111,36 @@ } return $mail_result; } + + /** + * Disallows potentially unsafe shell characters. + * + * Functionally similar to PHPMailer::isShellSafe() which resulted from + * CVE-2016-10045. Note that escapeshellarg and escapeshellcmd are inadequate + * for this purpose. + * + * @param string $string + * The string to be validated. + * + * @return bool + * True if the string is shell-safe. + * + * @see https://github.com/PHPMailer/PHPMailer/issues/924 + * @see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.phpmailer.php#L1430 + * + * @todo Rename to ::isShellSafe() and/or discuss whether this is the correct + * location for this helper. + */ + protected static function _isShellSafe($string) { + if (escapeshellcmd($string) !== $string || !in_array(escapeshellarg($string), array("'$string'", "\"$string\""))) { + return FALSE; + } + if (preg_match('/[^a-zA-Z0-9@_\-.]/', $string) !== 0) { + return FALSE; + } + return TRUE; + } + } /** diff -Naur drupal-7.56/modules/system/system.module drupal-7.66/modules/system/system.module --- drupal-7.56/modules/system/system.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.module 2019-04-17 22:20:46.000000000 +0200 @@ -1182,6 +1182,9 @@ 'version' => '1.4.4', 'js' => array( 'misc/jquery.js' => array('group' => JS_LIBRARY, 'weight' => -20), + // This includes a security fix, so assign a weight that makes this load + // as soon after jquery.js is loaded as possible. + 'misc/jquery-extend-3.4.0.js' => array('group' => JS_LIBRARY, 'weight' => -19), ), ); diff -Naur drupal-7.56/modules/system/system.tar.inc drupal-7.66/modules/system/system.tar.inc --- drupal-7.56/modules/system/system.tar.inc 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.tar.inc 2019-04-17 22:20:46.000000000 +0200 @@ -41,8 +41,8 @@ /** * Note on Drupal 8 porting. - * This file origin is Tar.php, release 1.4.0 (stable) with some code - * from PEAR.php, release 1.9.5 (stable) both at http://pear.php.net. + * This file origin is Tar.php, release 1.4.5 (stable) with some code + * from PEAR.php, release 1.10.5 (stable) both at http://pear.php.net. * To simplify future porting from pear of this file, you should not * do cosmetic or other non significant changes to this file. * The following changes have been done: @@ -259,6 +259,19 @@ return false; } } + + + if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { + $this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . + "a8checksum/a1typeflag/a100link/a6magic/a2version/" . + "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; + } else { + $this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . + "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . + "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; + } + + } public function __destruct() @@ -278,7 +291,7 @@ * @param string $ext The extension name * @return bool Success or not on the dl() call */ - function loadExtension($ext) + public static function loadExtension($ext) { if (extension_loaded($ext)) { return true; @@ -287,8 +300,7 @@ // if either returns true dl() will produce a FATAL error, stop that if ( function_exists('dl') === false || - ini_get('enable_dl') != 1 || - ini_get('safe_mode') == 1 + ini_get('enable_dl') != 1 ) { return false; } @@ -714,7 +726,7 @@ } // ----- Get the arguments - $v_att_list = & func_get_args(); + $v_att_list = func_get_args(); // ----- Read the attributes $i = 0; @@ -1394,10 +1406,22 @@ if ($p_stored_filename == '') { $p_stored_filename = $p_filename; } - $v_reduce_filename = $this->_pathReduction($p_stored_filename); - if (strlen($v_reduce_filename) > 99) { - if (!$this->_writeLongHeader($v_reduce_filename)) { + $v_reduced_filename = $this->_pathReduction($p_stored_filename); + + if (strlen($v_reduced_filename) > 99) { + if (!$this->_writeLongHeader($v_reduced_filename, false)) { + return false; + } + } + + $v_linkname = ''; + if (@is_link($p_filename)) { + $v_linkname = readlink($p_filename); + } + + if (strlen($v_linkname) > 99) { + if (!$this->_writeLongHeader($v_linkname, true)) { return false; } } @@ -1406,14 +1430,10 @@ $v_uid = sprintf("%07s", DecOct($v_info[4])); $v_gid = sprintf("%07s", DecOct($v_info[5])); $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); - $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); - $v_linkname = ''; - if (@is_link($p_filename)) { $v_typeflag = '2'; - $v_linkname = readlink($p_filename); $v_size = sprintf("%011s", DecOct(0)); } elseif (@is_dir($p_filename)) { $v_typeflag = "5"; @@ -1425,7 +1445,6 @@ } $v_magic = 'ustar '; - $v_version = ' '; if (function_exists('posix_getpwuid')) { @@ -1440,14 +1459,12 @@ } $v_devmajor = ''; - $v_devminor = ''; - $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", - $v_reduce_filename, + $v_reduced_filename, $v_perms, $v_uid, $v_gid, @@ -1487,7 +1504,7 @@ $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%06s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s\0 ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -1519,7 +1536,7 @@ $p_filename = $this->_pathReduction($p_filename); if (strlen($p_filename) > 99) { - if (!$this->_writeLongHeader($p_filename)) { + if (!$this->_writeLongHeader($p_filename, false)) { return false; } } @@ -1615,36 +1632,31 @@ * @param string $p_filename * @return bool */ - public function _writeLongHeader($p_filename) + public function _writeLongHeader($p_filename, $is_link = false) { - $v_size = sprintf("%11s ", DecOct(strlen($p_filename))); - - $v_typeflag = 'L'; - + $v_uid = sprintf("%07s", 0); + $v_gid = sprintf("%07s", 0); + $v_perms = sprintf("%07s", 0); + $v_size = sprintf("%'011s", DecOct(strlen($p_filename))); + $v_mtime = sprintf("%011s", 0); + $v_typeflag = ($is_link ? 'K' : 'L'); $v_linkname = ''; - - $v_magic = ''; - - $v_version = ''; - + $v_magic = 'ustar '; + $v_version = ' '; $v_uname = ''; - $v_gname = ''; - $v_devmajor = ''; - $v_devminor = ''; - $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", '././@LongLink', - 0, - 0, - 0, + $v_perms, + $v_uid, + $v_gid, $v_size, - 0 + $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", @@ -1679,7 +1691,7 @@ $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%06s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s\0 ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -1720,28 +1732,13 @@ // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header - for ($i = 0; $i < 148; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } - // ..... Ignore the checksum value and replace it by ' ' (space) - for ($i = 148; $i < 156; $i++) { - $v_checksum += ord(' '); - } - // ..... Last part of the header - for ($i = 156; $i < 512; $i++) { - $v_checksum += ord(substr($v_binary_data, $i, 1)); - } + $v_binary_split = str_split($v_binary_data); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); + $v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); + $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); - if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { - $fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . - "a8checksum/a1typeflag/a100link/a6magic/a2version/" . - "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; - } else { - $fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . - "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . - "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; - } - $v_data = unpack($fmt, $v_binary_data); + + $v_data = unpack($this->_fmt, $v_binary_data); if (strlen($v_data["prefix"]) > 0) { $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; @@ -1777,7 +1774,7 @@ $v_header['mode'] = OctDec(trim($v_data['mode'])); $v_header['uid'] = OctDec(trim($v_data['uid'])); $v_header['gid'] = OctDec(trim($v_data['gid'])); - $v_header['size'] = OctDec(trim($v_data['size'])); + $v_header['size'] = $this->_tarRecToSize($v_data['size']); $v_header['mtime'] = OctDec(trim($v_data['mtime'])); if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { $v_header['size'] = 0; @@ -1797,6 +1794,40 @@ } /** + * Convert Tar record size to actual size + * + * @param string $tar_size + * @return size of tar record in bytes + */ + private function _tarRecToSize($tar_size) + { + /* + * First byte of size has a special meaning if bit 7 is set. + * + * Bit 7 indicates base-256 encoding if set. + * Bit 6 is the sign bit. + * Bits 5:0 are most significant value bits. + */ + $ch = ord($tar_size[0]); + if ($ch & 0x80) { + // Full 12-bytes record is required. + $rec_str = $tar_size . "\x00"; + + $size = ($ch & 0x40) ? -1 : 0; + $size = ($size << 6) | ($ch & 0x3f); + + for ($num_ch = 1; $num_ch < 12; ++$num_ch) { + $size = ($size * 256) + ord($rec_str[$num_ch]); + } + + return $size; + + } else { + return OctDec(trim($tar_size)); + } + } + + /** * Detect and report a malicious file name * * @param string $file @@ -1805,10 +1836,13 @@ */ private function _maliciousFilename($file) { - if (strpos($file, '/../') !== false) { + if (strpos($file, 'phar://') === 0) { + return true; + } + if (strpos($file, DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) !== false) { return true; } - if (strpos($file, '../') === 0) { + if (strpos($file, '..' . DIRECTORY_SEPARATOR) === 0) { return true; } return false; @@ -1873,11 +1907,20 @@ continue; } - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) { - return null; - } + switch ($v_header['typeflag']) { + case 'L': { + if (!$this->_readLongHeader($v_header)) { + return null; + } + } break; + + case 'K': { + $v_link_header = $v_header; + if (!$this->_readLongHeader($v_link_header)) { + return null; + } + $v_header['link'] = $v_link_header['filename']; + } break; } if ($v_header['filename'] == $p_filename) { @@ -1978,11 +2021,20 @@ continue; } - // ----- Look for long filename - if ($v_header['typeflag'] == 'L') { - if (!$this->_readLongHeader($v_header)) { - return false; - } + switch ($v_header['typeflag']) { + case 'L': { + if (!$this->_readLongHeader($v_header)) { + return null; + } + } break; + + case 'K': { + $v_link_header = $v_header; + if (!$this->_readLongHeader($v_link_header)) { + return null; + } + $v_header['link'] = $v_link_header['filename']; + } break; } // ignore extended / pax headers diff -Naur drupal-7.56/modules/system/system.test drupal-7.66/modules/system/system.test --- drupal-7.56/modules/system/system.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/system/system.test 2019-04-17 22:20:46.000000000 +0200 @@ -1944,6 +1944,30 @@ $this->assertEqual($elements[0]['src'], file_create_url($uploaded_filename)); } + + /** + * Test the individual per-theme settings form. + */ + function testPerThemeSettings() { + // Enable the test theme and the module that controls it. Clear caches in + // between so that the module's hook_system_theme_info() implementation is + // correctly registered. + module_enable(array('theme_test')); + drupal_flush_all_caches(); + theme_enable(array('test_theme')); + + // Test that the theme-specific settings form can be saved and that the + // theme-specific checkbox is checked and unchecked as appropriate. + $this->drupalGet('admin/appearance/settings/test_theme'); + $this->assertNoFieldChecked('edit-test-theme-checkbox', 'The test_theme_checkbox setting is unchecked.'); + $this->drupalPost(NULL, array('test_theme_checkbox' => TRUE), t('Save configuration')); + $this->assertText('The test theme setting was saved.'); + $this->assertFieldChecked('edit-test-theme-checkbox', 'The test_theme_checkbox setting is checked.'); + $this->drupalPost(NULL, array('test_theme_checkbox' => FALSE), t('Save configuration')); + $this->assertText('The test theme setting was saved.'); + $this->assertNoFieldChecked('edit-test-theme-checkbox', 'The test_theme_checkbox setting is unchecked.'); + } + /** * Test the administration theme functionality. */ diff -Naur drupal-7.56/modules/system/tests/cron_queue_test.info drupal-7.66/modules/system/tests/cron_queue_test.info --- drupal-7.56/modules/system/tests/cron_queue_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/system/tests/cron_queue_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/system/tests/system_cron_test.info drupal-7.66/modules/system/tests/system_cron_test.info --- drupal-7.56/modules/system/tests/system_cron_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/system/tests/system_cron_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/taxonomy/taxonomy.info drupal-7.66/modules/taxonomy/taxonomy.info --- drupal-7.56/modules/taxonomy/taxonomy.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/taxonomy/taxonomy.info 2019-04-17 22:39:36.000000000 +0200 @@ -8,8 +8,7 @@ files[] = taxonomy.test configure = admin/structure/taxonomy -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/taxonomy/taxonomy.module drupal-7.66/modules/taxonomy/taxonomy.module --- drupal-7.56/modules/taxonomy/taxonomy.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/taxonomy/taxonomy.module 2019-04-17 22:20:46.000000000 +0200 @@ -283,6 +283,8 @@ 'title' => 'Taxonomy term', 'title callback' => 'taxonomy_term_title', 'title arguments' => array(2), + // The page callback also invokes drupal_set_title() in case + // the menu router's title is overridden by a menu link. 'page callback' => 'taxonomy_term_page', 'page arguments' => array(2), 'access arguments' => array('access content'), @@ -1714,13 +1716,15 @@ } /** - * Title callback for term pages. + * Title callback: Returns the title of the taxonomy term. * * @param $term * A term object. * * @return - * The term name to be used as the page title. + * An unsanitized string that is the title of the taxonomy term. + * + * @see taxonomy_menu() */ function taxonomy_term_title($term) { return $term->name; diff -Naur drupal-7.56/modules/toolbar/toolbar.info drupal-7.66/modules/toolbar/toolbar.info --- drupal-7.56/modules/toolbar/toolbar.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/toolbar/toolbar.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ package = Core version = VERSION -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/tracker/tracker.info drupal-7.66/modules/tracker/tracker.info --- drupal-7.56/modules/tracker/tracker.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/tracker/tracker.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ core = 7.x files[] = tracker.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/translation/tests/translation_test.info drupal-7.66/modules/translation/tests/translation_test.info --- drupal-7.56/modules/translation/tests/translation_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/translation/tests/translation_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/translation/translation.info drupal-7.66/modules/translation/translation.info --- drupal-7.56/modules/translation/translation.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/translation/translation.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ core = 7.x files[] = translation.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/trigger/tests/trigger_test.info drupal-7.66/modules/trigger/tests/trigger_test.info --- drupal-7.56/modules/trigger/tests/trigger_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/trigger/tests/trigger_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/trigger/trigger.info drupal-7.66/modules/trigger/trigger.info --- drupal-7.56/modules/trigger/trigger.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/trigger/trigger.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = trigger.test configure = admin/structure/trigger -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/aaa_update_test.info drupal-7.66/modules/update/tests/aaa_update_test.info --- drupal-7.56/modules/update/tests/aaa_update_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/aaa_update_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/bbb_update_test.info drupal-7.66/modules/update/tests/bbb_update_test.info --- drupal-7.56/modules/update/tests/bbb_update_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/bbb_update_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/ccc_update_test.info drupal-7.66/modules/update/tests/ccc_update_test.info --- drupal-7.56/modules/update/tests/ccc_update_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/ccc_update_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info drupal-7.66/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info --- drupal-7.56/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info 2019-04-17 22:39:36.000000000 +0200 @@ -3,8 +3,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info drupal-7.66/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info --- drupal-7.56/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info 2019-04-17 22:39:36.000000000 +0200 @@ -3,8 +3,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info drupal-7.66/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info --- drupal-7.56/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ base theme = update_test_basetheme hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/tests/update_test.info drupal-7.66/modules/update/tests/update_test.info --- drupal-7.56/modules/update/tests/update_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/tests/update_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/update/update.info drupal-7.66/modules/update/update.info --- drupal-7.56/modules/update/update.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/update/update.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ files[] = update.test configure = admin/reports/updates/settings -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/user/tests/user_form_test.info drupal-7.66/modules/user/tests/user_form_test.info --- drupal-7.56/modules/user/tests/user_form_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/user/tests/user_form_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/user/user.info drupal-7.66/modules/user/user.info --- drupal-7.56/modules/user/user.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/modules/user/user.info 2019-04-17 22:39:36.000000000 +0200 @@ -9,8 +9,7 @@ configure = admin/config/people stylesheets[all][] = user.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/modules/user/user.module drupal-7.66/modules/user/user.module --- drupal-7.56/modules/user/user.module 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/user/user.module 2019-04-17 22:20:46.000000000 +0200 @@ -637,7 +637,7 @@ if (strpos($name, ' ') !== FALSE) { return t('The username cannot contain multiple spaces in a row.'); } - if (preg_match('/[^\x{80}-\x{F7} a-z0-9@_.\'-]/i', $name)) { + if (preg_match('/[^\x{80}-\x{F7} a-z0-9@+_.\'-]/i', $name)) { return t('The username contains an illegal character.'); } if (preg_match('/[\x{80}-\x{A0}' . // Non-printable ISO-8859-1 + NBSP @@ -689,7 +689,7 @@ $validators = array( 'file_validate_is_image' => array(), 'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')), - 'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024), + 'file_validate_size' => array((int) variable_get('user_picture_file_size', '30') * 1024), ); // Save the file as a temporary file. diff -Naur drupal-7.56/modules/user/user.test drupal-7.66/modules/user/user.test --- drupal-7.56/modules/user/user.test 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/modules/user/user.test 2019-04-17 22:20:46.000000000 +0200 @@ -276,6 +276,7 @@ 'foo@example.com' => array('Valid username', 'assertNull'), 'foo@-example.com' => array('Valid username', 'assertNull'), // invalid domains are allowed in usernames 'þòøÇߪř€' => array('Valid username', 'assertNull'), + 'foo+bar' => array('Valid username', 'assertNull'), // '+' symbol is allowed 'ᚠᛇᚻ᛫ᛒᛦᚦ' => array('Valid UTF8 username', 'assertNull'), // runes ' foo' => array('Invalid username that starts with a space', 'assertNotNull'), 'foo ' => array('Invalid username that ends with a space', 'assertNotNull'), @@ -2386,7 +2387,13 @@ } function testUserSearch() { + // Verify that a user without 'administer users' permission cannot search + // for users by email address. Additionally, ensure that the username has a + // plus sign to ensure searching works with that. $user1 = $this->drupalCreateUser(array('access user profiles', 'search content', 'use advanced search')); + $edit['name'] = 'foo+bar'; + $edit['mail'] = $edit['name'] . '@example.com'; + user_save($user1, $edit); $this->drupalLogin($user1); $keys = $user1->mail; $edit = array('keys' => $keys); diff -Naur drupal-7.56/profiles/minimal/minimal.info drupal-7.66/profiles/minimal/minimal.info --- drupal-7.56/profiles/minimal/minimal.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/profiles/minimal/minimal.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ dependencies[] = block dependencies[] = dblog -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/profiles/standard/standard.info drupal-7.66/profiles/standard/standard.info --- drupal-7.56/profiles/standard/standard.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/profiles/standard/standard.info 2019-04-17 22:39:36.000000000 +0200 @@ -24,8 +24,7 @@ dependencies[] = file dependencies[] = rdf -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info drupal-7.66/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info --- drupal-7.56/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -6,8 +6,7 @@ hidden = TRUE files[] = drupal_system_listing_compatible_test.test -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info drupal-7.66/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info --- drupal-7.56/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info 2019-04-17 22:39:36.000000000 +0200 @@ -8,8 +8,7 @@ core = 6.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/profiles/testing/testing.info drupal-7.66/profiles/testing/testing.info --- drupal-7.56/profiles/testing/testing.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/profiles/testing/testing.info 2019-04-17 22:39:36.000000000 +0200 @@ -4,8 +4,7 @@ core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/sites/default/default.settings.php drupal-7.66/sites/default/default.settings.php --- drupal-7.56/sites/default/default.settings.php 2017-06-21 20:20:18.000000000 +0200 +++ drupal-7.66/sites/default/default.settings.php 2019-04-17 22:20:46.000000000 +0200 @@ -479,6 +479,23 @@ # $conf['block_cache_bypass_node_grants'] = TRUE; /** + * Expiration of cache_form entries: + * + * Drupal's Form API stores details of forms in cache_form and these entries are + * kept for at least 6 hours by default. Expired entries are cleared by cron. + * Busy sites can encounter problems with the cache_form table becoming very + * large. It's possible to mitigate this by setting a shorter expiration for + * cached forms. In some cases it may be desirable to set a longer cache + * expiration, for example to prolong cache_form entries for Ajax forms in + * cached HTML. + * + * @see form_set_cache() + * @see system_cron() + * @see ajax_get_form() + */ +# $conf['form_cache_expiration'] = 21600; + +/** * String overrides: * * To override specific strings on your site with or without enabling the Locale @@ -628,3 +645,17 @@ * @see drupal_clean_css_identifier() */ # $conf['allow_css_double_underscores'] = TRUE; + +/** + * The default list of directories that will be ignored by Drupal's file API. + * + * By default ignore node_modules and bower_components folders to avoid issues + * with common frontend tools and recursive scanning of directories looking for + * extensions. + * + * @see file_scan_directory() + */ +$conf['file_scan_ignore_directories'] = array( + 'node_modules', + 'bower_components', +); diff -Naur drupal-7.56/themes/bartik/bartik.info drupal-7.66/themes/bartik/bartik.info --- drupal-7.56/themes/bartik/bartik.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/themes/bartik/bartik.info 2019-04-17 22:39:36.000000000 +0200 @@ -34,8 +34,7 @@ settings[shortcut_module_link] = 0 -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/themes/garland/garland.info drupal-7.66/themes/garland/garland.info --- drupal-7.56/themes/garland/garland.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/themes/garland/garland.info 2019-04-17 22:39:36.000000000 +0200 @@ -7,8 +7,7 @@ stylesheets[print][] = print.css settings[garland_width] = fluid -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/themes/seven/seven.info drupal-7.66/themes/seven/seven.info --- drupal-7.56/themes/seven/seven.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/themes/seven/seven.info 2019-04-17 22:39:36.000000000 +0200 @@ -13,8 +13,7 @@ regions[sidebar_first] = First sidebar regions_hidden[] = sidebar_first -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576" diff -Naur drupal-7.56/themes/stark/stark.info drupal-7.66/themes/stark/stark.info --- drupal-7.56/themes/stark/stark.info 2017-06-21 20:30:49.000000000 +0200 +++ drupal-7.66/themes/stark/stark.info 2019-04-17 22:39:36.000000000 +0200 @@ -5,8 +5,7 @@ core = 7.x stylesheets[all][] = layout.css -; Information added by Drupal.org packaging script on 2017-06-21 -version = "7.56" +; Information added by Drupal.org packaging script on 2019-04-17 +version = "7.66" project = "drupal" -datestamp = "1498069849" - +datestamp = "1555533576"