diff --git a/admin/survey/SurveyAdminAjax.php b/admin/survey/SurveyAdminAjax.php index 99b501d6e..2e882b0d4 100644 --- a/admin/survey/SurveyAdminAjax.php +++ b/admin/survey/SurveyAdminAjax.php @@ -742,6 +742,14 @@ class SurveyAdminAjax { // naredi link za aktivacijo $code = base64_encode((hash('SHA256', time() .$pass_salt . $email. $rowU['name']))); + //Preverimo, koliko alternativnih emailov ima (dovolimo samo 10) + $sql_user_to_be = sisplet_query ("SELECT count(id) AS skupaj FROM users_to_be WHERE user_id='" . $global_user_id . "'"); + $row_user_to_be = mysqli_fetch_array($sql_user_to_be); + if($row_user_to_be['skupaj'] > 10){ + echo 'error'; + return true; + } + // Vstavimo novega userja v users_to_be kjer caka na aktivacijo $insert_id = sisplet_query ("INSERT INTO users_to_be (type, email, name, user_id, timecode, code, lang) diff --git a/frontend/drupal/CHANGELOG.txt b/frontend/drupal/CHANGELOG.txt index cda01053c..6bada936b 100644 --- a/frontend/drupal/CHANGELOG.txt +++ b/frontend/drupal/CHANGELOG.txt @@ -1,3 +1,36 @@ +Drupal 7.87, 2022-01-19 +----------------------- +- Fix regression caused by jQuery UI position() backport + +Drupal 7.86, 2022-01-18 +----------------------- +- Fixed security issues: + - SA-CORE-2022-001 + - SA-CORE-2022-002 + +Drupal 7.85, 2022-01-12 +----------------------- +- Fix session cookies for sites with different base_urls but a shared domain + +Drupal 7.84, 2021-12-13 +----------------------- +- Hotfix for session cookie domain on www subdomains + +Drupal 7.83, 2021-12-01 +----------------------- +- Initial support for PHP 8.1 +- The has_js cookie has been removed (but can be re-enabled) +- The leading www. is no longer stripped from cookie domain by default +- The user entity now has a "changed" property +- Introduced a skip_permissions_hardening setting +- Changes to the password reset process to avoid email and username enumeration +- Various bug fixes, optimizations and improvements + +Drupal 7.82, 2021-07-21 +----------------------- +- Fixed security issues: + - SA-CORE-2021-004 + Drupal 7.81, 2021-06-02 ----------------------- - Block Google FLoC by default diff --git a/frontend/drupal/includes/authorize.inc b/frontend/drupal/includes/authorize.inc index 8360e132c..1db326783 100644 --- a/frontend/drupal/includes/authorize.inc +++ b/frontend/drupal/includes/authorize.inc @@ -104,11 +104,6 @@ function authorize_filetransfer_form($form, &$form_state) { // Start non-JS code. if (isset($form_state['values']['connection_settings']['authorize_filetransfer_default']) && $form_state['values']['connection_settings']['authorize_filetransfer_default'] == $name) { - // If the user switches from JS to non-JS, Drupal (and Batch API) will - // barf. This is a known bug: http://drupal.org/node/229825. - setcookie('has_js', '', time() - 3600, '/'); - unset($_COOKIE['has_js']); - // Change the submit button to the submit_process one. $form['submit_process']['#attributes'] = array(); unset($form['submit_connection']); diff --git a/frontend/drupal/includes/batch.inc b/frontend/drupal/includes/batch.inc index 4d4e504d5..c98135beb 100644 --- a/frontend/drupal/includes/batch.inc +++ b/frontend/drupal/includes/batch.inc @@ -72,7 +72,9 @@ function _batch_page() { $output = NULL; switch ($op) { case 'start': - $output = _batch_start(); + // Display the full progress page on startup and on each additional + // non-JavaScript iteration. + $output = _batch_progress_page(); break; case 'do': @@ -82,7 +84,7 @@ function _batch_page() { case 'do_nojs': // Non-JavaScript-based progress page. - $output = _batch_progress_page_nojs(); + $output = _batch_progress_page(); break; case 'finished': @@ -93,69 +95,12 @@ function _batch_page() { return $output; } -/** - * Initializes the batch processing. - * - * JavaScript-enabled clients are identified by the 'has_js' cookie set in - * drupal.js. If no JavaScript-enabled page has been visited during the current - * user's browser session, the non-JavaScript version is returned. - */ -function _batch_start() { - if (isset($_COOKIE['has_js']) && $_COOKIE['has_js']) { - return _batch_progress_page_js(); - } - else { - return _batch_progress_page_nojs(); - } -} - -/** - * Outputs a batch processing page with JavaScript support. - * - * This initializes the batch and error messages. Note that in JavaScript-based - * processing, the batch processing page is displayed only once and updated via - * AHAH requests, so only the first batch set gets to define the page title. - * Titles specified by subsequent batch sets are not displayed. - * - * @see batch_set() - * @see _batch_do() - */ -function _batch_progress_page_js() { - $batch = batch_get(); - - $current_set = _batch_current_set(); - drupal_set_title($current_set['title'], PASS_THROUGH); - - // Merge required query parameters for batch processing into those provided by - // batch_set() or hook_batch_alter(). - $batch['url_options']['query']['id'] = $batch['id']; - - $js_setting = array( - 'batch' => array( - 'errorMessage' => $current_set['error_message'] . '
' . $batch['error_message'], - 'initMessage' => $current_set['init_message'], - 'uri' => url($batch['url'], $batch['url_options']), - ), - ); - drupal_add_js($js_setting, 'setting'); - drupal_add_library('system', 'drupal.batch'); - - return '
'; -} - /** * Does one execution pass with JavaScript and returns progress to the browser. * - * @see _batch_progress_page_js() * @see _batch_process() */ function _batch_do() { - // HTTP POST required. - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - drupal_set_message(t('HTTP POST is required.'), 'error'); - drupal_set_title(t('Error')); - return ''; - } // Perform actual processing. list($percentage, $message) = _batch_process(); @@ -164,11 +109,11 @@ function _batch_do() { } /** - * Outputs a batch processing page without JavaScript support. + * Outputs a batch processing page. * * @see _batch_process() */ -function _batch_progress_page_nojs() { +function _batch_progress_page() { $batch = &batch_get(); $current_set = _batch_current_set(); @@ -216,6 +161,9 @@ function _batch_progress_page_nojs() { $url = url($batch['url'], $batch['url_options']); $element = array( + // Redirect through a 'Refresh' meta tag if JavaScript is disabled. + '#prefix' => '', '#tag' => 'meta', '#attributes' => array( 'http-equiv' => 'Refresh', @@ -224,6 +172,17 @@ function _batch_progress_page_nojs() { ); drupal_add_html_head($element, 'batch_progress_meta_refresh'); + // Adds JavaScript code and settings for clients where JavaScript is enabled. + $js_setting = array( + 'batch' => array( + 'errorMessage' => $current_set['error_message'] . '
' . $batch['error_message'], + 'initMessage' => $current_set['init_message'], + 'uri' => $url, + ), + ); + drupal_add_js($js_setting, 'setting'); + drupal_add_library('system', 'drupal.batch'); + return theme('progress_bar', array('percent' => $percentage, 'message' => $message)); } diff --git a/frontend/drupal/includes/bootstrap.inc b/frontend/drupal/includes/bootstrap.inc index 2387e2b83..7e84531f9 100644 --- a/frontend/drupal/includes/bootstrap.inc +++ b/frontend/drupal/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.81'); +define('VERSION', '7.87'); /** * Core API compatibility. @@ -359,6 +359,7 @@ abstract class DrupalCacheArray implements ArrayAccess { /** * Implements ArrayAccess::offsetExists(). */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return $this->offsetGet($offset) !== NULL; } @@ -366,6 +367,7 @@ abstract class DrupalCacheArray implements ArrayAccess { /** * Implements ArrayAccess::offsetGet(). */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { if (isset($this->storage[$offset]) || array_key_exists($offset, $this->storage)) { return $this->storage[$offset]; @@ -378,6 +380,7 @@ abstract class DrupalCacheArray implements ArrayAccess { /** * Implements ArrayAccess::offsetSet(). */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->storage[$offset] = $value; } @@ -385,6 +388,7 @@ abstract class DrupalCacheArray implements ArrayAccess { /** * Implements ArrayAccess::offsetUnset(). */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->storage[$offset]); } @@ -803,14 +807,17 @@ function drupal_settings_initialize() { // HTTP_HOST can be modified by a visitor, but we already sanitized it // in drupal_settings_initialize(). if (!empty($_SERVER['HTTP_HOST'])) { - $cookie_domain = $_SERVER['HTTP_HOST']; - // Strip leading periods, www., and port numbers from cookie domain. - $cookie_domain = ltrim($cookie_domain, '.'); - if (strpos($cookie_domain, 'www.') === 0) { - $cookie_domain = substr($cookie_domain, 4); - } - $cookie_domain = explode(':', $cookie_domain); - $cookie_domain = '.' . $cookie_domain[0]; + $cookie_domain = _drupal_get_cookie_domain($_SERVER['HTTP_HOST']); + } + + // Drupal 7.83 included a security improvement whereby www. is no longer + // stripped from the cookie domain. However, this can cause problems with + // existing session cookies where some users are left unable to login. In + // order to avoid that, prepend a leading dot to the session_name that was + // derived from the base_url when a www. subdomain is in use. + // @see https://www.drupal.org/project/drupal/issues/2522002 + if (strpos($session_name, 'www.') === 0) { + $session_name = '.' . $session_name; } } // Per RFC 2109, cookie domains must contain at least one dot other than the @@ -831,6 +838,24 @@ function drupal_settings_initialize() { session_name($prefix . substr(hash('sha256', $session_name), 0, 32)); } +/** + * Derive the cookie domain to use for session cookies. + * + * @param $host + * The value of the HTTP host name. + * + * @return + * The string to use as a cookie domain. + */ +function _drupal_get_cookie_domain($host) { + $cookie_domain = $host; + // Strip leading periods and port numbers from cookie domain. + $cookie_domain = ltrim($cookie_domain, '.'); + $cookie_domain = explode(':', $cookie_domain); + $cookie_domain = '.' . $cookie_domain[0]; + return $cookie_domain; +} + /** * Returns and optionally sets the filename for a system resource. * @@ -1157,6 +1182,31 @@ function _drupal_trigger_error_with_delayed_logging($error_msg, $error_type = E_ $delay_logging = FALSE; } +/** + * Invoke trigger_error() using a fatal error that will terminate the request. + * + * Normally, Drupal's error handler does not terminate script execution on + * user-level errors, even if the error is of type E_USER_ERROR. This function + * triggers an error of type E_USER_ERROR that is explicitly forced to be a + * fatal error which terminates script execution. + * + * @param string $error_msg + * The error message to trigger. As with trigger_error() itself, this is + * limited to 1024 bytes; additional characters beyond that will be removed. + * + * @see _drupal_error_handler_real() + */ +function drupal_trigger_fatal_error($error_msg) { + $fatal_error = &drupal_static(__FUNCTION__, FALSE); + $fatal_error = TRUE; + trigger_error($error_msg, E_USER_ERROR); + $fatal_error = FALSE; + // The standard Drupal error handler should have treated this as a fatal + // error and already ended the page request. But in case another error + // handler is being used, terminate execution explicitly here also. + exit; +} + /** * Writes the file scan cache to the persistent cache. * @@ -2265,7 +2315,7 @@ function drupal_random_bytes($count) { // $random_state does not use drupal_static as it stores random bytes. static $random_state, $bytes, $has_openssl; - $missing_bytes = $count - strlen($bytes); + $missing_bytes = $count - strlen((string) $bytes); if ($missing_bytes > 0) { // PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes() diff --git a/frontend/drupal/includes/common.inc b/frontend/drupal/includes/common.inc index 2ca4fa06f..a65139f71 100644 --- a/frontend/drupal/includes/common.inc +++ b/frontend/drupal/includes/common.inc @@ -633,7 +633,7 @@ function drupal_parse_url($url) { * The Drupal path to encode. */ function drupal_encode_path($path) { - return str_replace('%2F', '/', rawurlencode($path)); + return str_replace('%2F', '/', rawurlencode((string) $path)); } /** @@ -943,7 +943,7 @@ function drupal_http_request($url, array $options = array()) { // or PUT request. Some non-standard servers get confused by Content-Length in // at least HEAD/GET requests, and Squid always requires Content-Length in // POST/PUT requests. - $content_length = strlen($options['data']); + $content_length = strlen((string) $options['data']); if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') { $options['headers']['Content-Length'] = $content_length; } @@ -1019,7 +1019,7 @@ function drupal_http_request($url, array $options = array()) { $result->headers = array(); // Parse the response headers. - while ($line = trim(array_shift($response))) { + while ($line = trim((string) array_shift($response))) { list($name, $value) = explode(':', $line, 2); $name = strtolower($name); if (isset($result->headers[$name]) && $name == 'set-cookie') { @@ -1916,7 +1916,7 @@ function format_plural($count, $singular, $plural, array $args = array(), array */ function parse_size($size) { $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size. - $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. + $size = (float) preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. if ($unit) { // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. return round($size * pow(DRUPAL_KILOBYTE, stripos('bkmgtpezy', $unit[0]))); @@ -1995,7 +1995,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) { $key = explode('|', $key); if ($interval >= $value) { $output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode)); - $interval %= $value; + $interval = (int) $interval % $value; $granularity--; } @@ -2308,7 +2308,7 @@ function url($path = NULL, array $options = array()) { // Strip leading slashes from internal paths to prevent them becoming external // URLs without protocol. /example.com should not be turned into // //example.com. - $path = ltrim($path, '/'); + $path = ltrim((string) $path, '/'); global $base_url, $base_secure_url, $base_insecure_url; @@ -2346,7 +2346,7 @@ function url($path = NULL, array $options = array()) { } $base = $options['absolute'] ? $options['base_url'] . '/' : base_path(); - $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix']; + $prefix = empty($path) ? rtrim((string) $options['prefix'], '/') : $options['prefix']; // With Clean URLs. if (!empty($GLOBALS['conf']['clean_url'])) { @@ -2390,6 +2390,7 @@ function url($path = NULL, array $options = array()) { * Boolean TRUE or FALSE, where TRUE indicates an external path. */ function url_is_external($path) { + $path = (string) $path; $colonpos = strpos($path, ':'); // Some browsers treat \ as / so normalize to forward slashes. $path = str_replace('\\', '/', $path); @@ -2944,12 +2945,12 @@ function base_path() { } /** - * Adds a LINK tag with a distinct 'rel' attribute to the page's HEAD. + * Adds a LINK tag with distinct attributes to the page's HEAD. * * This function can be called as long the HTML header hasn't been sent, which * on normal pages is up through the preprocess step of theme('html'). Adding - * a link will overwrite a prior link with the exact same 'rel' and 'href' - * attributes. + * a link will overwrite a prior link with the exact same 'rel', 'href' and + * 'hreflang' attributes. * * @param $attributes * Associative array of element attributes including 'href' and 'rel'. @@ -2965,12 +2966,12 @@ function drupal_add_html_head_link($attributes, $header = FALSE) { if ($header) { // Also add a HTTP header "Link:". - $href = '<' . check_plain($attributes['href']) . '>;'; + $href = '<' . $attributes['href'] . '>;'; unset($attributes['href']); $element['#attached']['drupal_add_http_header'][] = array('Link', $href . drupal_http_header_attributes($attributes), TRUE); } - drupal_add_html_head($element, 'drupal_add_html_head_link:' . $attributes['rel'] . ':' . $href); + drupal_add_html_head($element, 'drupal_add_html_head_link:' . $attributes['rel'] . ':' . (isset($attributes['hreflang']) ? "{$attributes['hreflang']}:" : '') . $href); } /** @@ -4342,6 +4343,7 @@ function drupal_add_js($data = NULL, $options = NULL) { 'data' => array( array('basePath' => base_path()), array('pathPrefix' => empty($prefix) ? '' : $prefix), + array('setHasJsCookie' => variable_get('set_has_js_cookie', FALSE) ? 1 : 0), ), 'type' => 'setting', 'scope' => 'header', @@ -6641,7 +6643,7 @@ function drupal_sort_title($a, $b) { * Checks if the key is a property. */ function element_property($key) { - return $key[0] == '#'; + return $key !== '' && is_string($key) && $key[0] == '#'; } /** diff --git a/frontend/drupal/includes/database/database.inc b/frontend/drupal/includes/database/database.inc index 61ac44f78..36999e7e8 100644 --- a/frontend/drupal/includes/database/database.inc +++ b/frontend/drupal/includes/database/database.inc @@ -1924,6 +1924,11 @@ class DatabaseTransactionOutOfOrderException extends Exception { } */ class InvalidMergeQueryException extends Exception {} +/** + * Exception thrown if an invalid query condition is specified. + */ +class InvalidQueryConditionOperatorException extends Exception {} + /** * Exception thrown if an insert query specifies a field twice. * @@ -2257,6 +2262,7 @@ class DatabaseStatementBase extends PDOStatement implements DatabaseStatementInt $this->setFetchMode(PDO::FETCH_OBJ); } + #[\ReturnTypeWillChange] public function execute($args = array(), $options = array()) { if (isset($options['fetch'])) { if (is_string($options['fetch'])) { @@ -2394,23 +2400,27 @@ class DatabaseStatementEmpty implements Iterator, DatabaseStatementInterface { } /* Implementations of Iterator. */ - + #[\ReturnTypeWillChange] public function current() { return NULL; } + #[\ReturnTypeWillChange] public function key() { return NULL; } + #[\ReturnTypeWillChange] public function rewind() { // Nothing to do: our DatabaseStatement can't be rewound. } + #[\ReturnTypeWillChange] public function next() { // Do nothing, since this is an always-empty implementation. } + #[\ReturnTypeWillChange] public function valid() { return FALSE; } diff --git a/frontend/drupal/includes/database/mysql/database.inc b/frontend/drupal/includes/database/mysql/database.inc index b83611198..8bb88d24f 100644 --- a/frontend/drupal/includes/database/mysql/database.inc +++ b/frontend/drupal/includes/database/mysql/database.inc @@ -332,6 +332,11 @@ class DatabaseConnection_mysql extends DatabaseConnection { PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE, // Because MySQL's prepared statements skip the query cache, because it's dumb. PDO::ATTR_EMULATE_PREPARES => TRUE, + // Convert numeric values to strings when fetching. In PHP 8.1, + // PDO::ATTR_EMULATE_PREPARES now behaves the same way as non emulated + // prepares and returns integers. See https://externals.io/message/113294 + // for further discussion. + PDO::ATTR_STRINGIFY_FETCHES => TRUE, ); if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) { // An added connection option in PHP 5.5.21+ to optionally limit SQL to a diff --git a/frontend/drupal/includes/database/prefetch.inc b/frontend/drupal/includes/database/prefetch.inc index 3b36a4e10..1211e4d45 100644 --- a/frontend/drupal/includes/database/prefetch.inc +++ b/frontend/drupal/includes/database/prefetch.inc @@ -268,6 +268,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface * @return * The current row formatted as requested. */ + #[\ReturnTypeWillChange] public function current() { if (isset($this->currentRow)) { switch ($this->fetchStyle) { @@ -320,14 +321,17 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface /* Implementations of Iterator. */ + #[\ReturnTypeWillChange] public function key() { return $this->currentKey; } + #[\ReturnTypeWillChange] public function rewind() { // Nothing to do: our DatabaseStatement can't be rewound. } + #[\ReturnTypeWillChange] public function next() { if (!empty($this->data)) { $this->currentRow = reset($this->data); @@ -339,6 +343,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface } } + #[\ReturnTypeWillChange] public function valid() { return isset($this->currentRow); } diff --git a/frontend/drupal/includes/database/query.inc b/frontend/drupal/includes/database/query.inc index 048c8a265..94b7a8fc9 100644 --- a/frontend/drupal/includes/database/query.inc +++ b/frontend/drupal/includes/database/query.inc @@ -871,8 +871,14 @@ class DeleteQuery extends Query implements QueryConditionInterface { $query = $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} '; if (count($this->condition)) { - - $this->condition->compile($this->connection, $this); + try { + $this->condition->compile($this->connection, $this); + } + // PHP does not allow exceptions to be thrown in __toString(), so trigger + // a fatal error instead. + catch (InvalidQueryConditionOperatorException $e) { + drupal_trigger_fatal_error($e->getMessage()); + } $query .= "\nWHERE " . $this->condition; } @@ -1204,7 +1210,14 @@ class UpdateQuery extends Query implements QueryConditionInterface { $query = $comments . 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields); if (count($this->condition)) { - $this->condition->compile($this->connection, $this); + try { + $this->condition->compile($this->connection, $this); + } + // PHP does not allow exceptions to be thrown in __toString(), so trigger + // a fatal error instead. + catch (InvalidQueryConditionOperatorException $e) { + drupal_trigger_fatal_error($e->getMessage()); + } // There is an implicit string cast on $this->condition. $query .= "\nWHERE " . $this->condition; } @@ -1697,6 +1710,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable { * size of its conditional array minus one, because one element is the * conjunction. */ + #[\ReturnTypeWillChange] public function count() { return count($this->conditions) - 1; } @@ -1789,6 +1803,8 @@ class DatabaseCondition implements QueryConditionInterface, Countable { /** * Implements QueryConditionInterface::compile(). + * + * @throws InvalidQueryConditionOperatorException */ public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder) { // Re-compile if this condition changed or if we are compiled against a @@ -1819,6 +1835,12 @@ class DatabaseCondition implements QueryConditionInterface, Countable { $arguments += $condition['field']->arguments(); } else { + // If the operator contains an invalid character, throw an + // exception to protect against SQL injection attempts. + if (stripos($condition['operator'], 'UNION') !== FALSE || strpbrk($condition['operator'], '[-\'"();') !== FALSE) { + throw new InvalidQueryConditionOperatorException('Invalid characters in query operator: ' . $condition['operator']); + } + // For simplicity, we treat all operators as the same data structure. // In the typical degenerate case, this won't get changed. $operator_defaults = array( diff --git a/frontend/drupal/includes/database/select.inc b/frontend/drupal/includes/database/select.inc index 674c6b53a..399ef6e4f 100644 --- a/frontend/drupal/includes/database/select.inc +++ b/frontend/drupal/includes/database/select.inc @@ -1504,7 +1504,14 @@ class SelectQuery extends Query implements SelectQueryInterface { // the query will be executed, it will be recompiled using the proper // placeholder generator anyway. if (!$this->compiled()) { - $this->compile($this->connection, $this); + try { + $this->compile($this->connection, $this); + } + // PHP does not allow exceptions to be thrown in __toString(), so trigger + // a fatal error instead. + catch (InvalidQueryConditionOperatorException $e) { + drupal_trigger_fatal_error($e->getMessage()); + } } // Create a sanitized comment string to prepend to the query. diff --git a/frontend/drupal/includes/database/sqlite/schema.inc b/frontend/drupal/includes/database/sqlite/schema.inc index 43ea6d61c..9d9ec895e 100644 --- a/frontend/drupal/includes/database/sqlite/schema.inc +++ b/frontend/drupal/includes/database/sqlite/schema.inc @@ -433,7 +433,7 @@ class DatabaseSchema_sqlite extends DatabaseSchema { 'type' => $type, 'size' => $size, 'not null' => !empty($row->notnull), - 'default' => trim($row->dflt_value, "'"), + 'default' => trim((string) $row->dflt_value, "'"), ); if ($length) { $schema['fields'][$row->name]['length'] = $length; diff --git a/frontend/drupal/includes/errors.inc b/frontend/drupal/includes/errors.inc index 4401ebe87..500b7b961 100644 --- a/frontend/drupal/includes/errors.inc +++ b/frontend/drupal/includes/errors.inc @@ -59,7 +59,8 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line) { require_once DRUPAL_ROOT . '/includes/common.inc'; } - // We treat recoverable errors as fatal. + // We treat recoverable errors as fatal, and also allow fatal errors to be + // explicitly triggered by drupal_trigger_fatal_error(). _drupal_log_error(array( '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error', // The standard PHP error handler considers that the error messages @@ -69,7 +70,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line) { '%file' => $caller['file'], '%line' => $caller['line'], 'severity_level' => $severity_level, - ), $error_level == E_RECOVERABLE_ERROR); + ), $error_level == E_RECOVERABLE_ERROR || drupal_static('drupal_trigger_fatal_error')); } } @@ -266,7 +267,7 @@ function _drupal_log_error($error, $fatal = FALSE) { function _drupal_get_last_caller($backtrace) { // Errors that occur inside PHP internal functions do not generate // information about file and line. Ignore black listed functions. - $blacklist = array('debug', '_drupal_error_handler', '_drupal_exception_handler'); + $blacklist = array('debug', '_drupal_error_handler', '_drupal_exception_handler', 'drupal_trigger_fatal_error'); while (($backtrace && !isset($backtrace[0]['line'])) || (isset($backtrace[1]['function']) && in_array($backtrace[1]['function'], $blacklist))) { array_shift($backtrace); diff --git a/frontend/drupal/includes/file.inc b/frontend/drupal/includes/file.inc index 013c435cf..8843ad7e3 100644 --- a/frontend/drupal/includes/file.inc +++ b/frontend/drupal/includes/file.inc @@ -197,7 +197,7 @@ function file_stream_wrapper_get_class($scheme) { * @see file_uri_target() */ function file_uri_scheme($uri) { - $position = strpos($uri, '://'); + $position = strpos((string) $uri, '://'); return $position ? substr($uri, 0, $position) : FALSE; } @@ -437,10 +437,10 @@ function file_prepare_directory(&$directory, $options = FILE_MODIFY_PERMISSIONS) // Check if directory exists. if (!is_dir($directory)) { - // Let mkdir() recursively create directories and use the default directory - // permissions. - if (($options & FILE_CREATE_DIRECTORY) && @drupal_mkdir($directory, NULL, TRUE)) { - return drupal_chmod($directory); + // Let drupal_mkdir() recursively create directories and use the default + // directory permissions. + if ($options & FILE_CREATE_DIRECTORY) { + return @drupal_mkdir($directory, NULL, TRUE); } return FALSE; } @@ -2481,19 +2481,21 @@ function drupal_basename($uri, $suffix = NULL) { } /** - * Creates a directory using Drupal's default mode. + * Creates a directory, optionally creating missing components in the path to + * the directory. * - * PHP's mkdir() does not respect Drupal's default permissions mode. If a mode - * is not provided, this function will make sure that Drupal's is used. - * - * Compatibility: normal paths and stream wrappers. + * When PHP's mkdir() creates a directory, the requested mode is affected by the + * process's umask. This function overrides the umask and sets the mode + * explicitly for all directory components created. * * @param $uri * A URI or pathname. * @param $mode - * By default the Drupal mode is used. + * Mode given to created directories. Defaults to the directory mode + * configured in the Drupal installation. It must have a leading zero. * @param $recursive - * Default to FALSE. + * Create directories recursively, defaults to FALSE. Cannot work with a mode + * which denies writing or execution to the owner of the process. * @param $context * Refer to http://php.net/manual/ref.stream.php * @@ -2509,7 +2511,71 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { $mode = variable_get('file_chmod_directory', 0775); } - if (!isset($context)) { + // If the URI has a scheme, don't override the umask - schemes can handle this + // issue in their own implementation. + if (file_uri_scheme($uri)) { + return _drupal_mkdir_call($uri, $mode, $recursive, $context); + } + + // If recursive, create each missing component of the parent directory + // individually and set the mode explicitly to override the umask. + if ($recursive) { + // Ensure the path is using DIRECTORY_SEPARATOR, and trim off any trailing + // slashes because they can throw off the loop when creating the parent + // directories. + $uri = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $uri), DIRECTORY_SEPARATOR); + // Determine the components of the path. + $components = explode(DIRECTORY_SEPARATOR, $uri); + // If the filepath is absolute the first component will be empty as there + // will be nothing before the first slash. + if ($components[0] == '') { + $recursive_path = DIRECTORY_SEPARATOR; + // Get rid of the empty first component. + array_shift($components); + } + else { + $recursive_path = ''; + } + // Don't handle the top-level directory in this loop. + array_pop($components); + // Create each component if necessary. + foreach ($components as $component) { + $recursive_path .= $component; + + if (!file_exists($recursive_path)) { + $success = _drupal_mkdir_call($recursive_path, $mode, FALSE, $context); + // If the operation failed, check again if the directory was created + // by another process/server, only report a failure if not. + if (!$success && !file_exists($recursive_path)) { + return FALSE; + } + // Not necessary to use self::chmod() as there is no scheme. + if (!chmod($recursive_path, $mode)) { + return FALSE; + } + } + + $recursive_path .= DIRECTORY_SEPARATOR; + } + } + + // Do not check if the top-level directory already exists, as this condition + // must cause this function to fail. + if (!_drupal_mkdir_call($uri, $mode, FALSE, $context)) { + return FALSE; + } + // Not necessary to use drupal_chmod() as there is no scheme. + return chmod($uri, $mode); +} + +/** + * Helper function. Ensures we don't pass a NULL as a context resource to + * mkdir(). + * + * @see drupal_mkdir() + */ +function _drupal_mkdir_call($uri, $mode, $recursive, $context) { + if (is_null($context)) { return mkdir($uri, $mode, $recursive); } else { diff --git a/frontend/drupal/includes/filetransfer/filetransfer.inc b/frontend/drupal/includes/filetransfer/filetransfer.inc index cd420bd06..2817b89d5 100644 --- a/frontend/drupal/includes/filetransfer/filetransfer.inc +++ b/frontend/drupal/includes/filetransfer/filetransfer.inc @@ -364,7 +364,7 @@ class FileTransferException extends Exception { public $arguments; function __construct($message, $code = 0, $arguments = array()) { - parent::__construct($message, $code); + parent::__construct($message, (int) $code); $this->arguments = $arguments; } } @@ -409,11 +409,13 @@ class SkipDotsRecursiveDirectoryIterator extends RecursiveDirectoryIterator { $this->skipdots(); } + #[\ReturnTypeWillChange] function rewind() { parent::rewind(); $this->skipdots(); } + #[\ReturnTypeWillChange] function next() { parent::next(); $this->skipdots(); diff --git a/frontend/drupal/includes/form.inc b/frontend/drupal/includes/form.inc index 3f6c7661a..eb68412fd 100644 --- a/frontend/drupal/includes/form.inc +++ b/frontend/drupal/includes/form.inc @@ -1393,7 +1393,10 @@ function _form_validate(&$elements, &$form_state, $form_id = NULL) { // identical to the empty option's value, we reset the element's value // to NULL to trigger the regular #required handling below. // @see form_process_select() - elseif ($elements['#type'] == 'select' && !$elements['#multiple'] && $elements['#required'] && !isset($elements['#default_value']) && $elements['#value'] === $elements['#empty_value']) { + elseif ($elements['#type'] == 'select' && $elements['#required'] + && (!array_key_exists('#multiple', $elements) || !$elements['#multiple']) + && !isset($elements['#default_value']) + && $elements['#value'] === $elements['#empty_value']) { $elements['#value'] = NULL; form_set_value($elements, NULL, $form_state); } diff --git a/frontend/drupal/includes/install.core.inc b/frontend/drupal/includes/install.core.inc index b18d23d21..2e4c491a7 100644 --- a/frontend/drupal/includes/install.core.inc +++ b/frontend/drupal/includes/install.core.inc @@ -1505,8 +1505,19 @@ function install_configure_form($form, &$form_state, &$install_state) { // especially out of place on the last page of the installer, where it would // distract from the message that the Drupal installation has completed // successfully.) - if (empty($_POST) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) { - drupal_set_message(st('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the online handbook.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning'); + + $skip_permissions_hardening = variable_get('skip_permissions_hardening', FALSE); + // Allow system administrators to ignore permissions hardening for the site + // directory. This allows additional files in the site directory to be + // updated when they are managed in a version control system. + if (!$skip_permissions_hardening) { + if (empty($_POST) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) { + drupal_set_message(st('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the online handbook.', array( + '%dir' => $settings_dir, + '%file' => $settings_file, + '@handbook_url' => 'http://drupal.org/server-permissions' + )), 'warning'); + } } drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); diff --git a/frontend/drupal/includes/install.inc b/frontend/drupal/includes/install.inc index b7db78358..8f9137be3 100644 --- a/frontend/drupal/includes/install.inc +++ b/frontend/drupal/includes/install.inc @@ -830,11 +830,14 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents * An optional bitmask created from various FILE_* constants. * @param $type * The type of file. Can be file (default), dir, or link. + * @param bool $autofix + * (optional) Determines whether to attempt fixing the permissions according + * to the provided $mask. Defaults to TRUE. * * @return * TRUE on success or FALSE on failure. A message is set for the latter. */ -function drupal_verify_install_file($file, $mask = NULL, $type = 'file') { +function drupal_verify_install_file($file, $mask = NULL, $type = 'file', $autofix = TRUE) { $return = TRUE; // Check for files that shouldn't be there. if (isset($mask) && ($mask & FILE_NOT_EXIST) && file_exists($file)) { @@ -856,7 +859,7 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') { switch ($current_mask) { case FILE_EXIST: if (!file_exists($file)) { - if ($type == 'dir') { + if ($type == 'dir' && $autofix) { drupal_install_mkdir($file, $mask); } if (!file_exists($file)) { @@ -865,32 +868,32 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') { } break; case FILE_READABLE: - if (!is_readable($file) && !drupal_install_fix_file($file, $mask)) { + if (!is_readable($file)) { $return = FALSE; } break; case FILE_WRITABLE: - if (!is_writable($file) && !drupal_install_fix_file($file, $mask)) { + if (!is_writable($file)) { $return = FALSE; } break; case FILE_EXECUTABLE: - if (!is_executable($file) && !drupal_install_fix_file($file, $mask)) { + if (!is_executable($file)) { $return = FALSE; } break; case FILE_NOT_READABLE: - if (is_readable($file) && !drupal_install_fix_file($file, $mask)) { + if (is_readable($file)) { $return = FALSE; } break; case FILE_NOT_WRITABLE: - if (is_writable($file) && !drupal_install_fix_file($file, $mask)) { + if (is_writable($file)) { $return = FALSE; } break; case FILE_NOT_EXECUTABLE: - if (is_executable($file) && !drupal_install_fix_file($file, $mask)) { + if (is_executable($file)) { $return = FALSE; } break; @@ -898,6 +901,9 @@ function drupal_verify_install_file($file, $mask = NULL, $type = 'file') { } } } + if (!$return && $autofix) { + return drupal_install_fix_file($file, $mask); + } return $return; } diff --git a/frontend/drupal/includes/iso.inc b/frontend/drupal/includes/iso.inc index 5cad329d9..e15c35731 100644 --- a/frontend/drupal/includes/iso.inc +++ b/frontend/drupal/includes/iso.inc @@ -327,7 +327,7 @@ function _locale_get_predefined_list() { 'da' => array('Danish', 'Dansk'), 'de' => array('German', 'Deutsch'), 'dv' => array('Maldivian'), - 'dz' => array('Bhutani'), + 'dz' => array('Dzongkha', 'རྫོང་ཁ'), 'ee' => array('Ewe', 'Ɛʋɛ'), 'el' => array('Greek', 'Ελληνικά'), 'en' => array('English'), diff --git a/frontend/drupal/includes/menu.inc b/frontend/drupal/includes/menu.inc index b97927511..519ce8af5 100644 --- a/frontend/drupal/includes/menu.inc +++ b/frontend/drupal/includes/menu.inc @@ -3203,7 +3203,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a 'external' => $item['external'], 'has_children' => $item['has_children'], 'expanded' => $item['expanded'], - 'weight' => $item['weight'], + 'weight' => (int) $item['weight'], 'module' => $item['module'], 'link_title' => $item['link_title'], 'options' => serialize($item['options']), @@ -3267,7 +3267,7 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a 'external' => $item['external'], 'has_children' => $item['has_children'], 'expanded' => $item['expanded'], - 'weight' => $item['weight'], + 'weight' => (int) $item['weight'], 'depth' => $item['depth'], 'p1' => $item['p1'], 'p2' => $item['p2'], @@ -3906,7 +3906,7 @@ function _menu_router_save($menu, $masks) { 'type' => $item['type'], 'description' => $item['description'], 'position' => $item['position'], - 'weight' => $item['weight'], + 'weight' => (int) $item['weight'], 'include_file' => $item['include file'], )); diff --git a/frontend/drupal/includes/session.inc b/frontend/drupal/includes/session.inc index a4ce54b7d..1f3c1773b 100644 --- a/frontend/drupal/includes/session.inc +++ b/frontend/drupal/includes/session.inc @@ -106,7 +106,7 @@ function _drupal_session_read($sid) { // active user. if ($user && $user->uid > 0 && $user->status == 1) { // This is done to unserialize the data member of $user. - $user->data = unserialize($user->data); + $user->data = unserialize((string) $user->data); // Add roles element to $user. $user->roles = array(); diff --git a/frontend/drupal/includes/stream_wrappers.inc b/frontend/drupal/includes/stream_wrappers.inc index 232ff1437..31101674b 100644 --- a/frontend/drupal/includes/stream_wrappers.inc +++ b/frontend/drupal/includes/stream_wrappers.inc @@ -784,10 +784,10 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface $localpath = $this->getLocalPath($uri); } if ($options & STREAM_REPORT_ERRORS) { - return mkdir($localpath, $mode, $recursive); + return drupal_mkdir($localpath, $mode, $recursive); } else { - return @mkdir($localpath, $mode, $recursive); + return @drupal_mkdir($localpath, $mode, $recursive); } } diff --git a/frontend/drupal/includes/unicode.inc b/frontend/drupal/includes/unicode.inc index f9684a897..4c61ce143 100644 --- a/frontend/drupal/includes/unicode.inc +++ b/frontend/drupal/includes/unicode.inc @@ -589,6 +589,7 @@ function drupal_ucfirst($text) { */ function drupal_substr($text, $start, $length = NULL) { global $multibyte; + $text = (string) $text; if ($multibyte == UNICODE_MULTIBYTE) { return $length === NULL ? mb_substr($text, $start) : mb_substr($text, $start, $length); } diff --git a/frontend/drupal/misc/batch.js b/frontend/drupal/misc/batch.js index fee71a52f..998879e4a 100644 --- a/frontend/drupal/misc/batch.js +++ b/frontend/drupal/misc/batch.js @@ -7,6 +7,9 @@ Drupal.behaviors.batch = { attach: function (context, settings) { $('#progress', context).once('batch', function () { var holder = $(this); + // Remove HTML from no-js progress bar. The JS progress bar is created + // later on. + holder.empty(); // Success: redirect to the summary. var updateCallback = function (progress, status, pb) { diff --git a/frontend/drupal/misc/drupal.js b/frontend/drupal/misc/drupal.js index 7a3f5f592..07692fcbc 100644 --- a/frontend/drupal/misc/drupal.js +++ b/frontend/drupal/misc/drupal.js @@ -588,8 +588,12 @@ Drupal.ajaxError = function (xmlhttp, uri, customMessage) { // Class indicating that JS is enabled; used for styling purpose. $('html').addClass('js'); -// 'js enabled' cookie. -document.cookie = 'has_js=1; path=/'; +$(function () { + if (Drupal.settings.setHasJsCookie === 1) { + // 'js enabled' cookie. + document.cookie = 'has_js=1; path=/; SameSite=Lax'; + } +}); /** * Additions to jQuery.support. diff --git a/frontend/drupal/misc/ui/jquery.ui.datepicker-1.13.0-backport.js b/frontend/drupal/misc/ui/jquery.ui.datepicker-1.13.0-backport.js new file mode 100644 index 000000000..9cb92b023 --- /dev/null +++ b/frontend/drupal/misc/ui/jquery.ui.datepicker-1.13.0-backport.js @@ -0,0 +1,36 @@ +/** + * Backport of security fixes from: + * https://github.com/jquery/jquery-ui/pull/1953 + * https://github.com/jquery/jquery-ui/pull/1954 + */ + +(function ($, Drupal) { + + // No backport is needed if we're already on jQuery UI 1.13 or higher. + var versionParts = $.ui.datepicker.version.split('.'); + var majorVersion = parseInt(versionParts[0]); + var minorVersion = parseInt(versionParts[1]); + if ( (majorVersion > 1) || (majorVersion === 1 && minorVersion >= 13) ) { + return; + } + + var fnOriginalGet = $.datepicker._get; + $.extend($.datepicker, { + + _get: function( inst, name ) { + var val = fnOriginalGet.call(this, inst, name); + + // @see https://github.com/jquery/jquery-ui/pull/1954 + if (name === 'altField') { + val = $(document).find(val); + } + // @see https://github.com/jquery/jquery-ui/pull/1953 + else if ($.inArray(name, ['appendText', 'buttonText', 'prevText', 'currentText', 'nextText', 'closeText']) !== -1) { + val = Drupal.checkPlain(val); + } + + return val; + } + + }) +})(jQuery, Drupal); diff --git a/frontend/drupal/misc/ui/jquery.ui.dialog-1.13.0-backport.js b/frontend/drupal/misc/ui/jquery.ui.dialog-1.13.0-backport.js new file mode 100644 index 000000000..564092d9e --- /dev/null +++ b/frontend/drupal/misc/ui/jquery.ui.dialog-1.13.0-backport.js @@ -0,0 +1,58 @@ +/** + * Backport of security fixes from: + * https://bugs.jqueryui.com/ticket/6016 + * https://github.com/jquery/jquery-ui/pull/1635/files + */ + +(function ($) { + + // Parts of this backport differ by jQuery version. + var versionParts = $.ui.dialog.version.split('.'); + var majorVersion = parseInt(versionParts[0]); + var minorVersion = parseInt(versionParts[1]); + + if (majorVersion === 1 && minorVersion < 13) { + var _originalSetOption = $.ui.dialog.prototype._setOption; + var _originalCreateTitlebar = $.ui.dialog.prototype._createTitlebar; + + $.extend($.ui.dialog.prototype, { + + _createTitlebar: function () { + if (this.options.closeText) { + this.options.closeText = Drupal.checkPlain(this.options.closeText); + } + _originalCreateTitlebar.apply(this, arguments); + }, + + _setOption: function (key, value) { + if (key === 'title' || key == 'closeText') { + if (value) { + value = Drupal.checkPlain(value); + } + } + _originalSetOption.apply(this, [key, value]); + } + }); + + if (majorVersion === 1 && minorVersion < 10) { + var _originalCreate = $.ui.dialog.prototype._create; + + $.extend($.ui.dialog.prototype, { + + _create: function () { + if (!this.options.title) { + var defaultTitle = this.element.attr('title'); + // .attr() might return a DOMElement + if (typeof defaultTitle !== "string") { + defaultTitle = ""; + } + this.options.title = defaultTitle; + } + this.options.title = Drupal.checkPlain(this.options.title); + _originalCreate.apply(this, arguments); + }, + }); + } + } + +})(jQuery); diff --git a/frontend/drupal/misc/ui/jquery.ui.position-1.13.0-backport.js b/frontend/drupal/misc/ui/jquery.ui.position-1.13.0-backport.js new file mode 100644 index 000000000..6567e5e2f --- /dev/null +++ b/frontend/drupal/misc/ui/jquery.ui.position-1.13.0-backport.js @@ -0,0 +1,33 @@ +/** + * Backport of security fix from: + * https://github.com/jquery/jquery-ui/pull/1955/files + */ + +(function ($) { + + // No backport is needed if we're already on jQuery UI 1.13 or higher. + var versionParts = $.ui.version.split('.'); + var majorVersion = parseInt(versionParts[0]); + var minorVersion = parseInt(versionParts[1]); + if ( (majorVersion > 1) || (majorVersion === 1 && minorVersion >= 13) ) { + return; + } + + var fnOriginalPosition = $.fn.position; + $.fn.extend({ + 'position': function (options) { + if (typeof options === 'undefined') { + return fnOriginalPosition.call(this); + } + + // Make sure string options are treated as CSS selectors + var target = typeof options.of === "string" ? + $(document).find(options.of) : + $(options.of); + + options.of = (target[0] === undefined) ? null : target; + return fnOriginalPosition.call(this, options); + } + }); + +})(jQuery); diff --git a/frontend/drupal/modules/aggregator/aggregator.info b/frontend/drupal/modules/aggregator/aggregator.info index 9814958fe..e526ce61f 100644 --- a/frontend/drupal/modules/aggregator/aggregator.info +++ b/frontend/drupal/modules/aggregator/aggregator.info @@ -7,7 +7,7 @@ files[] = aggregator.test configure = admin/config/services/aggregator/settings stylesheets[all][] = aggregator.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/aggregator/tests/aggregator_test.info b/frontend/drupal/modules/aggregator/tests/aggregator_test.info index 25e6ac2bf..b80988a30 100644 --- a/frontend/drupal/modules/aggregator/tests/aggregator_test.info +++ b/frontend/drupal/modules/aggregator/tests/aggregator_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/block/block.info b/frontend/drupal/modules/block/block.info index 0315b069b..6b6c2bc73 100644 --- a/frontend/drupal/modules/block/block.info +++ b/frontend/drupal/modules/block/block.info @@ -6,7 +6,7 @@ core = 7.x files[] = block.test configure = admin/structure/block -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/block/tests/block_test.info b/frontend/drupal/modules/block/tests/block_test.info index e352c4577..9dd5437de 100644 --- a/frontend/drupal/modules/block/tests/block_test.info +++ b/frontend/drupal/modules/block/tests/block_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/block/tests/themes/block_test_theme/block_test_theme.info b/frontend/drupal/modules/block/tests/themes/block_test_theme/block_test_theme.info index 899b7b72a..782bce798 100644 --- a/frontend/drupal/modules/block/tests/themes/block_test_theme/block_test_theme.info +++ b/frontend/drupal/modules/block/tests/themes/block_test_theme/block_test_theme.info @@ -13,7 +13,7 @@ regions[footer] = Footer regions[highlighted] = Highlighted regions[help] = Help -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/blog/blog.info b/frontend/drupal/modules/blog/blog.info index b4bdbecef..a55373bbf 100644 --- a/frontend/drupal/modules/blog/blog.info +++ b/frontend/drupal/modules/blog/blog.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = blog.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/book/book.info b/frontend/drupal/modules/book/book.info index c2d7f7d1c..cfe2dd6bb 100644 --- a/frontend/drupal/modules/book/book.info +++ b/frontend/drupal/modules/book/book.info @@ -7,7 +7,7 @@ files[] = book.test configure = admin/content/book/settings stylesheets[all][] = book.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/color/color.info b/frontend/drupal/modules/color/color.info index a94a318f8..f33dc97d1 100644 --- a/frontend/drupal/modules/color/color.info +++ b/frontend/drupal/modules/color/color.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = color.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/color/color.module b/frontend/drupal/modules/color/color.module index 45acd788f..583a20322 100644 --- a/frontend/drupal/modules/color/color.module +++ b/frontend/drupal/modules/color/color.module @@ -724,7 +724,7 @@ function _color_blend($img, $hex1, $hex2, $alpha) { $in2 = _color_unpack($hex2); $out = array($img); for ($i = 0; $i < 3; ++$i) { - $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha; + $out[] = (int) ($in1[$i] + ($in2[$i] - $in1[$i]) * $alpha); } return call_user_func_array('imagecolorallocate', $out); @@ -752,7 +752,7 @@ function _color_unpack($hex, $normalize = FALSE) { function _color_pack($rgb, $normalize = FALSE) { $out = 0; foreach ($rgb as $k => $v) { - $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8)); + $out |= (((int) ($v * ($normalize ? 255 : 1))) << (16 - $k * 8)); } return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT); diff --git a/frontend/drupal/modules/color/color.test b/frontend/drupal/modules/color/color.test index f29c0c267..bac17a847 100644 --- a/frontend/drupal/modules/color/color.test +++ b/frontend/drupal/modules/color/color.test @@ -131,3 +131,53 @@ class ColorTestCase extends DrupalWebTestCase { } } } + +/** + * Unit tests for the color.module + */ +class ColorUnitTestCase extends DrupalUnitTestCase { + + protected $test_values; + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'Color module unit tests', + 'description' => 'Test color.module functionality.', + 'group' => 'Color', + ); + } + + /** + * Set up the test environment. + */ + public function setUp() { + drupal_load('module', 'color'); + parent::setUp(); + + $this->test_values = array( + array(array(0.2, 0.4, 0.8), TRUE, '#3366cc'), + array(array(51, 102, 204), FALSE, '#3366cc'), + array(array(6, 120, 190), FALSE, '#0678be'), + array(array(192, 192, 192), FALSE, '#c0c0c0'), + array(array(255, 255, 0), FALSE, '#ffff00'), + array(array(128, 0, 128), FALSE, '#800080'), + array(array(0.6, 0.8, 1), TRUE, '#99ccff'), + array(array(221, 72, 20), FALSE, '#dd4814'), + ); + } + + public function testColorPack() { + foreach ($this->test_values as $test) { + $this->assertEqual(_color_pack($test[0], $test[1]), $test[2], __FUNCTION__ . ' hex: ' . $test[2] . ' normalize: ' . ($test[1] ? 'TRUE' : 'FALSE')); + } + } + + public function testColorUnpack() { + foreach ($this->test_values as $test) { + $this->assertEqual(_color_unpack($test[2], $test[1]), $test[0], __FUNCTION__ . ' hex: ' . $test[2] . ' normalize: ' . ($test[1] ? 'TRUE' : 'FALSE')); + } + } +} diff --git a/frontend/drupal/modules/comment/comment.info b/frontend/drupal/modules/comment/comment.info index 4d11958cc..93be7a6da 100644 --- a/frontend/drupal/modules/comment/comment.info +++ b/frontend/drupal/modules/comment/comment.info @@ -9,7 +9,7 @@ files[] = comment.test configure = admin/content/comment stylesheets[all][] = comment.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/comment/comment.module b/frontend/drupal/modules/comment/comment.module index 6f0df6cae..23fb2f5d3 100644 --- a/frontend/drupal/modules/comment/comment.module +++ b/frontend/drupal/modules/comment/comment.module @@ -1515,7 +1515,7 @@ function comment_save($comment) { // by retrieving the maximum thread level. $max = db_query('SELECT MAX(thread) FROM {comment} WHERE nid = :nid', array(':nid' => $comment->nid))->fetchField(); // Strip the "/" from the end of the thread. - $max = rtrim($max, '/'); + $max = rtrim((string) $max, '/'); // We need to get the value at the correct depth. $parts = explode('.', $max); $firstsegment = $parts[0]; diff --git a/frontend/drupal/modules/contact/contact.info b/frontend/drupal/modules/contact/contact.info index 533d0c026..2cec0208f 100644 --- a/frontend/drupal/modules/contact/contact.info +++ b/frontend/drupal/modules/contact/contact.info @@ -6,7 +6,7 @@ core = 7.x files[] = contact.test configure = admin/structure/contact -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/contextual/contextual.info b/frontend/drupal/modules/contextual/contextual.info index f77a83cd5..f1dc6ee27 100644 --- a/frontend/drupal/modules/contextual/contextual.info +++ b/frontend/drupal/modules/contextual/contextual.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = contextual.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/dashboard/dashboard.info b/frontend/drupal/modules/dashboard/dashboard.info index 3661e5601..50ee571b2 100644 --- a/frontend/drupal/modules/dashboard/dashboard.info +++ b/frontend/drupal/modules/dashboard/dashboard.info @@ -7,7 +7,7 @@ files[] = dashboard.test dependencies[] = block configure = admin/dashboard/customize -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/dblog/dblog.info b/frontend/drupal/modules/dblog/dblog.info index 0dbbe15be..68ecd6325 100644 --- a/frontend/drupal/modules/dblog/dblog.info +++ b/frontend/drupal/modules/dblog/dblog.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = dblog.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/field.info b/frontend/drupal/modules/field/field.info index 6839caa3a..97df803e4 100644 --- a/frontend/drupal/modules/field/field.info +++ b/frontend/drupal/modules/field/field.info @@ -11,7 +11,7 @@ dependencies[] = field_sql_storage required = TRUE stylesheets[all][] = theme/field.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/field_sql_storage/field_sql_storage.info b/frontend/drupal/modules/field/modules/field_sql_storage/field_sql_storage.info index dcd907f0c..495cb352f 100644 --- a/frontend/drupal/modules/field/modules/field_sql_storage/field_sql_storage.info +++ b/frontend/drupal/modules/field/modules/field_sql_storage/field_sql_storage.info @@ -7,7 +7,7 @@ dependencies[] = field files[] = field_sql_storage.test required = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/list/list.info b/frontend/drupal/modules/field/modules/list/list.info index 579dc142a..6639e2373 100644 --- a/frontend/drupal/modules/field/modules/list/list.info +++ b/frontend/drupal/modules/field/modules/list/list.info @@ -7,7 +7,7 @@ dependencies[] = field dependencies[] = options files[] = tests/list.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/list/list.module b/frontend/drupal/modules/field/modules/list/list.module index 634c13488..976f13c8b 100644 --- a/frontend/drupal/modules/field/modules/list/list.module +++ b/frontend/drupal/modules/field/modules/list/list.module @@ -67,7 +67,7 @@ function list_field_settings_form($field, $instance, $has_data) { $form['allowed_values'] = array( '#type' => 'textarea', '#title' => t('Allowed values list'), - '#default_value' => list_allowed_values_string($settings['allowed_values']), + '#default_value' => empty($settings['allowed_values_function']) ? list_allowed_values_string($settings['allowed_values']) : array(), '#rows' => 10, '#element_validate' => array('list_allowed_values_setting_validate'), '#field_has_data' => $has_data, diff --git a/frontend/drupal/modules/field/modules/list/tests/list.test b/frontend/drupal/modules/field/modules/list/tests/list.test index b476b5aad..7c3aec0c4 100644 --- a/frontend/drupal/modules/field/modules/list/tests/list.test +++ b/frontend/drupal/modules/field/modules/list/tests/list.test @@ -406,18 +406,36 @@ class ListFieldUITestCase extends FieldTestCase { $this->assertFalse(isset($field['settings']['off']), 'The off value is not saved into settings'); } + /** + * List (text) : test 'allowed values function' input. + */ + function testDynamicListAllowedValuesText() { + $this->field_name = 'field_list_text'; + $this->createListField('list_text', array( + 'allowed_values_function' => 'list_test_dynamic_values_callback', + 'allowed_values' => '', + )); + $this->drupalGet($this->admin_path); + } + /** * Helper function to create list field of a given type. * * @param string $type * 'list_integer', 'list_float', 'list_text' or 'list_boolean' + * @param array $settings + * + * @throws \FieldException */ - protected function createListField($type) { + protected function createListField($type, $settings = array()) { // Create a test field and instance. $field = array( 'field_name' => $this->field_name, 'type' => $type, ); + if (!empty($settings)) { + $field['settings'] = $settings; + } field_create_field($field); $instance = array( 'field_name' => $this->field_name, diff --git a/frontend/drupal/modules/field/modules/list/tests/list_test.info b/frontend/drupal/modules/field/modules/list/tests/list_test.info index 1790ae689..6da787cc4 100644 --- a/frontend/drupal/modules/field/modules/list/tests/list_test.info +++ b/frontend/drupal/modules/field/modules/list/tests/list_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/number/number.info b/frontend/drupal/modules/field/modules/number/number.info index 3b102f21a..78876c785 100644 --- a/frontend/drupal/modules/field/modules/number/number.info +++ b/frontend/drupal/modules/field/modules/number/number.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = field files[] = number.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/options/options.info b/frontend/drupal/modules/field/modules/options/options.info index e39194426..d8ca08651 100644 --- a/frontend/drupal/modules/field/modules/options/options.info +++ b/frontend/drupal/modules/field/modules/options/options.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = field files[] = options.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/modules/text/text.info b/frontend/drupal/modules/field/modules/text/text.info index 039f9352a..670c70f38 100644 --- a/frontend/drupal/modules/field/modules/text/text.info +++ b/frontend/drupal/modules/field/modules/text/text.info @@ -7,7 +7,7 @@ dependencies[] = field files[] = text.test required = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field/tests/field_test.info b/frontend/drupal/modules/field/tests/field_test.info index a0ddebee5..97ddf1281 100644 --- a/frontend/drupal/modules/field/tests/field_test.info +++ b/frontend/drupal/modules/field/tests/field_test.info @@ -6,7 +6,7 @@ files[] = field_test.entity.inc version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/field_ui/field_ui.info b/frontend/drupal/modules/field_ui/field_ui.info index 5c23008d1..0d64e0926 100644 --- a/frontend/drupal/modules/field_ui/field_ui.info +++ b/frontend/drupal/modules/field_ui/field_ui.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = field files[] = field_ui.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/file/file.field.inc b/frontend/drupal/modules/file/file.field.inc index ddb4f841f..973031629 100644 --- a/frontend/drupal/modules/file/file.field.inc +++ b/frontend/drupal/modules/file/file.field.inc @@ -20,7 +20,7 @@ function file_field_info() { ), 'instance_settings' => array( 'file_extensions' => 'txt', - 'file_directory' => '', + 'file_directory' => '[date:custom:Y]-[date:custom:m]', 'max_filesize' => '', 'description_field' => 0, ), diff --git a/frontend/drupal/modules/file/file.info b/frontend/drupal/modules/file/file.info index a10872a01..a78b935a0 100644 --- a/frontend/drupal/modules/file/file.info +++ b/frontend/drupal/modules/file/file.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = field files[] = tests/file.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/file/tests/file.test b/frontend/drupal/modules/file/tests/file.test index c8264349d..3f9c6de88 100644 --- a/frontend/drupal/modules/file/tests/file.test +++ b/frontend/drupal/modules/file/tests/file.test @@ -1354,10 +1354,11 @@ class FileFieldPathTestCase extends FileFieldTestCase { // Create a new node. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); - // Check that the file was uploaded to the file root. + // Check that the file was uploaded to the correct location. $node = node_load($nid, NULL, TRUE); $node_file = (object) $node->{$field_name}[LANGUAGE_NONE][0]; - $this->assertPathMatch('public://' . $test_file->filename, $node_file->uri, format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->uri))); + $expected_path = 'public://' . date('Y', REQUEST_TIME) . '-' . date('m', REQUEST_TIME) . '/' . $test_file->filename; + $this->assertPathMatch($expected_path, $node_file->uri, format_string('The file %file was uploaded to the correct path.', array('%file' => $node_file->uri))); // Change the path to contain multiple subdirectories. $field = $this->updateFileField($field_name, $type_name, array('file_directory' => 'foo/bar/baz')); diff --git a/frontend/drupal/modules/file/tests/file_module_test.info b/frontend/drupal/modules/file/tests/file_module_test.info index 17ba53a57..a3c20290d 100644 --- a/frontend/drupal/modules/file/tests/file_module_test.info +++ b/frontend/drupal/modules/file/tests/file_module_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/filter/filter.info b/frontend/drupal/modules/filter/filter.info index 421e1d649..154d7a895 100644 --- a/frontend/drupal/modules/filter/filter.info +++ b/frontend/drupal/modules/filter/filter.info @@ -7,7 +7,7 @@ files[] = filter.test required = TRUE configure = admin/config/content/formats -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/filter/filter.module b/frontend/drupal/modules/filter/filter.module index e9fd01d38..6b911cb8a 100644 --- a/frontend/drupal/modules/filter/filter.module +++ b/frontend/drupal/modules/filter/filter.module @@ -785,7 +785,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE) // Convert all Windows and Mac newlines to a single newline, so filters only // need to deal with one possibility. - $text = str_replace(array("\r\n", "\r"), "\n", $text); + $text = str_replace(array("\r\n", "\r"), "\n", (string) $text); // Get a complete list of filters, ordered properly. $filters = filter_list_format($format->format); @@ -1661,7 +1661,7 @@ function _filter_url_trim($text, $length = NULL) { } // Use +3 for '...' string length. - if ($_length && strlen($text) > $_length + 3) { + if ($_length && strlen((string) $text) > $_length + 3) { $text = substr($text, 0, $_length) . '...'; } diff --git a/frontend/drupal/modules/forum/forum.info b/frontend/drupal/modules/forum/forum.info index 536373c9c..7e7db9f64 100644 --- a/frontend/drupal/modules/forum/forum.info +++ b/frontend/drupal/modules/forum/forum.info @@ -9,7 +9,7 @@ files[] = forum.test configure = admin/structure/forum stylesheets[all][] = forum.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/help/help.info b/frontend/drupal/modules/help/help.info index e88bd0263..49c04ad56 100644 --- a/frontend/drupal/modules/help/help.info +++ b/frontend/drupal/modules/help/help.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = help.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/image/image.effects.inc b/frontend/drupal/modules/image/image.effects.inc index 35a6a74c7..cbdb13609 100644 --- a/frontend/drupal/modules/image/image.effects.inc +++ b/frontend/drupal/modules/image/image.effects.inc @@ -259,7 +259,7 @@ function image_rotate_effect(&$image, $data) { ); // Convert short #FFF syntax to full #FFFFFF syntax. - if (strlen($data['bgcolor']) == 4) { + if (strlen((string) $data['bgcolor']) == 4) { $c = $data['bgcolor']; $data['bgcolor'] = $c[0] . $c[1] . $c[1] . $c[2] . $c[2] . $c[3] . $c[3]; } diff --git a/frontend/drupal/modules/image/image.field.inc b/frontend/drupal/modules/image/image.field.inc index 6d1867cb0..f0dbf2718 100644 --- a/frontend/drupal/modules/image/image.field.inc +++ b/frontend/drupal/modules/image/image.field.inc @@ -19,7 +19,7 @@ function image_field_info() { ), 'instance_settings' => array( 'file_extensions' => 'png gif jpg jpeg', - 'file_directory' => '', + 'file_directory' => '[date:custom:Y]-[date:custom:m]', 'max_filesize' => '', 'alt_field' => 0, 'title_field' => 0, diff --git a/frontend/drupal/modules/image/image.info b/frontend/drupal/modules/image/image.info index a26d4813b..dc119f3ff 100644 --- a/frontend/drupal/modules/image/image.info +++ b/frontend/drupal/modules/image/image.info @@ -7,7 +7,7 @@ dependencies[] = file files[] = image.test configure = admin/config/media/image-styles -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/image/image.module b/frontend/drupal/modules/image/image.module index dab88361a..71fba3797 100644 --- a/frontend/drupal/modules/image/image.module +++ b/frontend/drupal/modules/image/image.module @@ -804,7 +804,7 @@ function image_style_options($include_empty = TRUE, $output = CHECK_PLAIN) { * @param $scheme * The file scheme, for example 'public' for public files. */ -function image_style_deliver($style, $scheme) { +function image_style_deliver($style, $scheme = NULL) { $args = func_get_args(); array_shift($args); array_shift($args); @@ -817,7 +817,7 @@ function image_style_deliver($style, $scheme) { // site's vulnerability to denial-of-service attacks. To prevent this // variable from leaving the site vulnerable to the most serious attacks, a // token is always required when a derivative of a derivative is requested.) - $valid = !empty($style) && file_stream_wrapper_valid_scheme($scheme); + $valid = !empty($style) && !empty($scheme) && file_stream_wrapper_valid_scheme($scheme); if (!variable_get('image_allow_insecure_derivatives', FALSE) || strpos(ltrim($target, '\/'), 'styles/') === 0) { $valid = $valid && isset($_GET[IMAGE_DERIVATIVE_TOKEN]) && $_GET[IMAGE_DERIVATIVE_TOKEN] === image_style_path_token($style['name'], $scheme . '://' . $target); } diff --git a/frontend/drupal/modules/image/image.test b/frontend/drupal/modules/image/image.test index 22edcaa06..07eb4cedc 100644 --- a/frontend/drupal/modules/image/image.test +++ b/frontend/drupal/modules/image/image.test @@ -378,6 +378,11 @@ class ImageStylesPathAndUrlTestCase extends DrupalWebTestCase { $directory = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/' . $this->randomName(); $this->drupalGet(file_create_url($directory . '/' . $this->randomName())); $this->assertFalse(file_exists($directory), 'New directory was not created in the filesystem when requesting an unauthorized image.'); + + // Check that requesting a partial image style path returns access denied. + $partial_url = $scheme . '://styles/' . $this->style_name . '/'; + $this->drupalGet(file_create_url($partial_url) . '/'); + $this->assertResponse(403, 'Access was denied to a partial image style path.'); } } diff --git a/frontend/drupal/modules/image/tests/image_module_test.info b/frontend/drupal/modules/image/tests/image_module_test.info index 627606909..1a8b2990e 100644 --- a/frontend/drupal/modules/image/tests/image_module_test.info +++ b/frontend/drupal/modules/image/tests/image_module_test.info @@ -6,7 +6,7 @@ core = 7.x files[] = image_module_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/locale/locale.info b/frontend/drupal/modules/locale/locale.info index 0b9b08f7c..1e8d97980 100644 --- a/frontend/drupal/modules/locale/locale.info +++ b/frontend/drupal/modules/locale/locale.info @@ -6,7 +6,7 @@ core = 7.x files[] = locale.test configure = admin/config/regional/language -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/locale/tests/locale_test.info b/frontend/drupal/modules/locale/tests/locale_test.info index d8bbf12ef..a59890c22 100644 --- a/frontend/drupal/modules/locale/tests/locale_test.info +++ b/frontend/drupal/modules/locale/tests/locale_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/menu/menu.admin.inc b/frontend/drupal/modules/menu/menu.admin.inc index c21f08dbc..4d0a792dd 100644 --- a/frontend/drupal/modules/menu/menu.admin.inc +++ b/frontend/drupal/modules/menu/menu.admin.inc @@ -59,13 +59,8 @@ function menu_overview_form($form, &$form_state, $menu) { foreach ($result as $item) { $links[] = $item; } - - /** - * 1KA iskanje - */ - $link_count = db_query("SELECT COUNT(*) AS counter FROM {menu_links} WHERE menu_name = :menu AND link_path NOT LIKE :link_path", array(':menu' => $menu['menu_name'], ':link_path' => '%\%%'))->fetchObject(); - $counter = intval($link_count->counter / 2 ) + 1; - + $link_count = db_query("SELECT COUNT(*) AS counter FROM {menu_links} WHERE menu_name = :menu AND link_path NOT LIKE :link_path", array(':menu' => $menu['menu_name'], ':link_path' => '%\%%'))->fetchObject(); + $counter = intval($link_count->counter / 2 ) + 1; $tree = menu_tree_data($links); $node_links = array(); @@ -75,12 +70,8 @@ function menu_overview_form($form, &$form_state, $menu) { menu_tree_check_access($tree, $node_links); $menu_admin = FALSE; - /** - * 1KA menu - */ $delta = _menu_get_menu_weight_delta($menu['menu_name'], $counter); $form = array_merge($form, _menu_overview_tree_form($tree, $delta)); - $form['#menu'] = $menu; if (element_children($form)) { @@ -100,10 +91,11 @@ function menu_overview_form($form, &$form_state, $menu) { * Recursive helper function for menu_overview_form(). * * @param $tree - * * @param $delta + * The menu_tree retrieved by menu_tree_data. + * @param $delta * The number of items to use in the menu weight selector. Defaults to 50. */ -function _menu_overview_tree_form($tree, $delta = 50) { +function _menu_overview_tree_form($tree, $delta = 50) { $form = &drupal_static(__FUNCTION__, array('#tree' => TRUE)); foreach ($tree as $data) { $title = ''; @@ -114,12 +106,7 @@ function _menu_overview_tree_form($tree, $delta = 50) { $form[$mlid]['#item'] = $item; $form[$mlid]['#attributes'] = $item['hidden'] ? array('class' => array('menu-disabled')) : array('class' => array('menu-enabled')); $form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']); - if ($item['hidden']) { - $form[$mlid]['title']['#markup'] .= ' (' . t('disabled') . ')'; - } - elseif ($item['link_path'] == 'user' && $item['module'] == 'system') { - $form[$mlid]['title']['#markup'] .= ' (' . t('logged in users only') . ')'; - } + menu_add_link_labels($form[$mlid]['title']['#markup'], $item); $form[$mlid]['hidden'] = array( '#type' => 'checkbox', @@ -157,8 +144,7 @@ function _menu_overview_tree_form($tree, $delta = 50) { } if ($data['below']) { - # 1ka menu $delta - _menu_overview_tree_form($data['below'], $delta); + _menu_overview_tree_form($data['below'], $delta); } } return $form; @@ -373,20 +359,17 @@ function menu_edit_item($form, &$form_state, $type, $item, $menu) { '#description' => t('The maximum depth for a link and all its children is fixed at !maxdepth. Some menu links may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)), '#attributes' => array('class' => array('menu-title-select')), ); - - /** - * 1ka menu - */ - // Get number of items in all possible parent menus so the weight selector is sized appropriately. - $menu_names = array_keys(menu_get_menus()); - $menu_options = array(); - foreach ($menu_names as $menu_name) { - if (isset($options[$menu_name . ':0'])) { - $menu_options[] = $menu_name; - } + // Get number of items in all possible parent menus so the weight selector is + // sized appropriately. + $menu_names = array_keys(menu_get_menus()); + $menu_options = array(); + foreach ($menu_names as $menu_name) { + if (isset($options[$menu_name . ':0'])) { + $menu_options[] = $menu_name; } - // Make sure that we always have values in menu_options. - $menu_options = !empty($menu_options) ? $menu_options : $menu_names; + } + // Make sure that we always have values in menu_options. + $menu_options = !empty($menu_options) ? $menu_options : $menu_names; $form['weight'] = array( '#type' => 'weight', diff --git a/frontend/drupal/modules/menu/menu.info b/frontend/drupal/modules/menu/menu.info index e5c167c25..35dd7ea97 100644 --- a/frontend/drupal/modules/menu/menu.info +++ b/frontend/drupal/modules/menu/menu.info @@ -6,7 +6,7 @@ core = 7.x files[] = menu.test configure = admin/structure/menu -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/menu/menu.module b/frontend/drupal/modules/menu/menu.module index 7e129c9f6..c6cb548b1 100644 --- a/frontend/drupal/modules/menu/menu.module +++ b/frontend/drupal/modules/menu/menu.module @@ -42,39 +42,6 @@ function menu_help($path, $arg) { } } -/** - * Calculate weight's delta for a menu or group of menu options. - * - * @param string|array $menu_names - * Menu name or an array of menu names to caclulate its weight's delta. - * @param integer $max_delta - * Optional value, delta's maximum value. - * - * @return int - * Delta value for the given menu name or menu names. - */ -function _menu_get_menu_weight_delta($menu_names, $max_delta = NULL) { - - if (is_string($menu_names)) { - $menu_names = array($menu_names); - } - - $weight_info = db_query("SELECT MAX(weight) AS max_weight, MIN(weight) as min_weight FROM {menu_links} WHERE menu_name IN (:menu_names)", array(':menu_names' => $menu_names))->fetchObject(); - - $delta = max(abs($weight_info->min_weight), abs($weight_info->max_weight)) + 1; - - // Honor max param, if given. - if (!is_null($max_delta) && $delta > $max_delta) { - $delta = $max_delta; - } - - // At minimum use the old hardcoded value. - if ($delta < 50) { - $delta = 50; - } - return $delta; -} - /** * Implements hook_permission(). */ @@ -434,6 +401,9 @@ function menu_parent_options_js() { * Helper function to get the items of the given menu. */ function _menu_get_options($menus, $available_menus, $item) { + global $menu_admin; + $menu_admin = TRUE; + // If the item has children, there is an added limit to the depth of valid parents. if (isset($item['parent_depth_limit'])) { $limit = $item['parent_depth_limit']; @@ -450,6 +420,8 @@ function _menu_get_options($menus, $available_menus, $item) { _menu_parents_recurse($tree, $menu_name, '--', $options, $item['mlid'], $limit); } } + + $menu_admin = FALSE; return $options; } @@ -464,9 +436,7 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, } if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) { $title = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, FALSE); - if ($data['link']['hidden']) { - $title .= ' (' . t('disabled') . ')'; - } + menu_add_link_labels($title, $data['link']); $options[$menu_name . ':' . $data['link']['mlid']] = $title; if ($data['below']) { _menu_parents_recurse($data['below'], $menu_name, $indent . '--', $options, $exclude, $depth_limit); @@ -475,6 +445,27 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, } } +/** + * Adds labels to the title of a hidden, unpublished or logged-in menu link. + * + * @param string $title + * The title of the menu link. This will be modified as necessary to add the + * appropriate label in parentheses at the end. + * @param array $item + * An array representing the menu link item. + */ +function menu_add_link_labels(&$title, $item) { + if ($item['hidden']) { + $title .= ' (' . t('disabled') . ')'; + } + elseif (!empty($item['node_unpublished'])) { + $title .= ' (' . t('unpublished') . ')'; + } + elseif ($item['link_path'] == 'user' && $item['module'] == 'system') { + $title .= ' (' . t('logged in users only') . ')'; + } +} + /** * Reset a system-defined menu link. */ @@ -649,6 +640,39 @@ function _menu_parent_depth_limit($item) { return MENU_MAX_DEPTH - 1 - (($item['mlid'] && $item['has_children']) ? menu_link_children_relative_depth($item) : 0); } +/** + * Calculate the delta for the weight element for a given set of menus. + * + * @param string|array $menu_names + * Menu name or an array of menu names. + * @param int $max_delta + * Optional maximum value. + * + * @return int + * Delta value. + */ +function _menu_get_menu_weight_delta($menu_names, $max_delta = NULL) { + + if (is_string($menu_names)) { + $menu_names = array($menu_names); + } + + $weight_info = db_query("SELECT MAX(weight) AS max_weight, MIN(weight) as min_weight FROM {menu_links} WHERE menu_name IN (:menu_names)", array(':menu_names' => $menu_names))->fetchObject(); + + $delta = max(abs((int) $weight_info->min_weight), abs((int) $weight_info->max_weight)) + 1; + + // Honor max param, if given. + if (!is_null($max_delta) && $delta > $max_delta) { + $delta = $max_delta; + } + + // Provide a minimum. + if ($delta < 50) { + $delta = 50; + } + return $delta; +} + /** * Implements hook_form_BASE_FORM_ID_alter(). * @@ -735,17 +759,17 @@ function menu_form_node_form_alter(&$form, $form_state) { '#options' => $options, '#attributes' => array('class' => array('menu-parent-select')), ); - - // Get number of items in all possible parent menus so the weight selector is sized appropriately. - $menu_names = array_keys(menu_get_menus()); - $menu_options = array(); - foreach ($menu_names as $menu_name) { - if (isset($options[$menu_name . ':0'])) { - $menu_options[] = $menu_name; - } + // Get number of items in all possible parent menus so the weight selector is + // sized appropriately. + $menu_names = array_keys(menu_get_menus()); + $menu_options = array(); + foreach ($menu_names as $menu_name) { + if (isset($options[$menu_name . ':0'])) { + $menu_options[] = $menu_name; } - // Make sure that we always have values in menu_options. - $menu_options = !empty($menu_options) ? $menu_options : $menu_names; + } + // Make sure that we always have values in menu_options. + $menu_options = !empty($menu_options) ? $menu_options : $menu_names; $form['menu']['link']['weight'] = array( '#type' => 'weight', diff --git a/frontend/drupal/modules/node/node.api.php b/frontend/drupal/modules/node/node.api.php index c8176a7d3..1a0c3a99f 100644 --- a/frontend/drupal/modules/node/node.api.php +++ b/frontend/drupal/modules/node/node.api.php @@ -747,10 +747,10 @@ function hook_node_update_index($node) { /** * Perform node validation before a node is created or updated. * - * This hook is invoked from node_validate(), after a user has has finished - * editing the node and is previewing or submitting it. It is invoked at the - * end of all the standard validation steps, and after the type-specific - * hook_validate() is invoked. + * This hook is invoked from node_validate(), after a user has finished editing + * the node and is previewing or submitting it. It is invoked at the end of all + * the standard validation steps, and after the type-specific hook_validate() is + * invoked. * * To indicate a validation error, use form_set_error(). * diff --git a/frontend/drupal/modules/node/node.info b/frontend/drupal/modules/node/node.info index 11cc29203..4b87789fe 100644 --- a/frontend/drupal/modules/node/node.info +++ b/frontend/drupal/modules/node/node.info @@ -9,7 +9,7 @@ required = TRUE configure = admin/structure/types stylesheets[all][] = node.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/node/tests/node_access_test.info b/frontend/drupal/modules/node/tests/node_access_test.info index 15322d681..a66001a2d 100644 --- a/frontend/drupal/modules/node/tests/node_access_test.info +++ b/frontend/drupal/modules/node/tests/node_access_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/node/tests/node_test.info b/frontend/drupal/modules/node/tests/node_test.info index 9680680ac..46ab8e457 100644 --- a/frontend/drupal/modules/node/tests/node_test.info +++ b/frontend/drupal/modules/node/tests/node_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/node/tests/node_test_exception.info b/frontend/drupal/modules/node/tests/node_test_exception.info index a18fd1c02..b941cb27b 100644 --- a/frontend/drupal/modules/node/tests/node_test_exception.info +++ b/frontend/drupal/modules/node/tests/node_test_exception.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/openid/openid.inc b/frontend/drupal/modules/openid/openid.inc index 4ca747164..87a0d4d75 100644 --- a/frontend/drupal/modules/openid/openid.inc +++ b/frontend/drupal/modules/openid/openid.inc @@ -445,7 +445,7 @@ function _openid_signature($association, $message_array, $keys_to_sign) { } $message = _openid_create_message($sign_data); - $secret = base64_decode($association->mac_key); + $secret = base64_decode((string) $association->mac_key); $signature = _openid_hmac($secret, $message); return base64_encode($signature); diff --git a/frontend/drupal/modules/openid/openid.info b/frontend/drupal/modules/openid/openid.info index 8b46933cd..97b188cda 100644 --- a/frontend/drupal/modules/openid/openid.info +++ b/frontend/drupal/modules/openid/openid.info @@ -5,7 +5,7 @@ package = Core core = 7.x files[] = openid.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/openid/tests/openid_test.info b/frontend/drupal/modules/openid/tests/openid_test.info index e12b3757c..fb5d7e763 100644 --- a/frontend/drupal/modules/openid/tests/openid_test.info +++ b/frontend/drupal/modules/openid/tests/openid_test.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = openid hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/overlay/overlay.info b/frontend/drupal/modules/overlay/overlay.info index 488a77326..dc0d20180 100644 --- a/frontend/drupal/modules/overlay/overlay.info +++ b/frontend/drupal/modules/overlay/overlay.info @@ -4,7 +4,7 @@ package = Core version = VERSION core = 7.x -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/path/path.info b/frontend/drupal/modules/path/path.info index a3129aaf5..949c7e069 100644 --- a/frontend/drupal/modules/path/path.info +++ b/frontend/drupal/modules/path/path.info @@ -6,7 +6,7 @@ core = 7.x files[] = path.test configure = admin/config/search/path -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/php/php.info b/frontend/drupal/modules/php/php.info index cfd6349ca..2afe099ce 100644 --- a/frontend/drupal/modules/php/php.info +++ b/frontend/drupal/modules/php/php.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = php.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/poll/poll.info b/frontend/drupal/modules/poll/poll.info index a23b62480..8baa11ab7 100644 --- a/frontend/drupal/modules/poll/poll.info +++ b/frontend/drupal/modules/poll/poll.info @@ -6,7 +6,7 @@ core = 7.x files[] = poll.test stylesheets[all][] = poll.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/profile/profile.info b/frontend/drupal/modules/profile/profile.info index 1b8ab1dad..aa642ab32 100644 --- a/frontend/drupal/modules/profile/profile.info +++ b/frontend/drupal/modules/profile/profile.info @@ -11,7 +11,7 @@ configure = admin/config/people/profile ; See user_system_info_alter(). hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/rdf/rdf.info b/frontend/drupal/modules/rdf/rdf.info index 74c38cd49..8c5190407 100644 --- a/frontend/drupal/modules/rdf/rdf.info +++ b/frontend/drupal/modules/rdf/rdf.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x files[] = rdf.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/rdf/tests/rdf_test.info b/frontend/drupal/modules/rdf/tests/rdf_test.info index df4ee0b5f..824dbf033 100644 --- a/frontend/drupal/modules/rdf/tests/rdf_test.info +++ b/frontend/drupal/modules/rdf/tests/rdf_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE dependencies[] = blog -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/search/search.info b/frontend/drupal/modules/search/search.info index c673507e3..b1b4fff36 100644 --- a/frontend/drupal/modules/search/search.info +++ b/frontend/drupal/modules/search/search.info @@ -8,7 +8,7 @@ files[] = search.test configure = admin/config/search/settings stylesheets[all][] = search.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/search/tests/search_embedded_form.info b/frontend/drupal/modules/search/tests/search_embedded_form.info index 000ad5e00..6d8457d53 100644 --- a/frontend/drupal/modules/search/tests/search_embedded_form.info +++ b/frontend/drupal/modules/search/tests/search_embedded_form.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/search/tests/search_extra_type.info b/frontend/drupal/modules/search/tests/search_extra_type.info index c73c41bac..6db64af98 100644 --- a/frontend/drupal/modules/search/tests/search_extra_type.info +++ b/frontend/drupal/modules/search/tests/search_extra_type.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/search/tests/search_node_tags.info b/frontend/drupal/modules/search/tests/search_node_tags.info index e3c551b4a..6210f1691 100644 --- a/frontend/drupal/modules/search/tests/search_node_tags.info +++ b/frontend/drupal/modules/search/tests/search_node_tags.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/shortcut/shortcut.info b/frontend/drupal/modules/shortcut/shortcut.info index 660236ad9..0240c0c81 100644 --- a/frontend/drupal/modules/shortcut/shortcut.info +++ b/frontend/drupal/modules/shortcut/shortcut.info @@ -6,7 +6,7 @@ core = 7.x files[] = shortcut.test configure = admin/config/user-interface/shortcut -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/drupal_web_test_case.php b/frontend/drupal/modules/simpletest/drupal_web_test_case.php index e2dc2322d..a3bd3730c 100644 --- a/frontend/drupal/modules/simpletest/drupal_web_test_case.php +++ b/frontend/drupal/modules/simpletest/drupal_web_test_case.php @@ -1536,7 +1536,7 @@ class DrupalWebTestCase extends DrupalTestCase { // Inform others that this cache is usable now. $cache_file = $this->originalFileDirectory . '/simpletest/' . $cache_key . '/simpletest-cache-setup'; - file_put_contents($cache_file, time(NULL)); + file_put_contents($cache_file, time()); lock_release($lock_key); return TRUE; diff --git a/frontend/drupal/modules/simpletest/simpletest.info b/frontend/drupal/modules/simpletest/simpletest.info index 7d503300a..a654fb7cc 100644 --- a/frontend/drupal/modules/simpletest/simpletest.info +++ b/frontend/drupal/modules/simpletest/simpletest.info @@ -58,7 +58,7 @@ files[] = tests/upgrade/update.trigger.test files[] = tests/upgrade/update.field.test files[] = tests/upgrade/update.user.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/actions_loop_test.info b/frontend/drupal/modules/simpletest/tests/actions_loop_test.info index d84f0939e..e1758c436 100644 --- a/frontend/drupal/modules/simpletest/tests/actions_loop_test.info +++ b/frontend/drupal/modules/simpletest/tests/actions_loop_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/ajax_forms_test.info b/frontend/drupal/modules/simpletest/tests/ajax_forms_test.info index 3c9acfc7f..4ca9c5790 100644 --- a/frontend/drupal/modules/simpletest/tests/ajax_forms_test.info +++ b/frontend/drupal/modules/simpletest/tests/ajax_forms_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/ajax_test.info b/frontend/drupal/modules/simpletest/tests/ajax_test.info index 4b8b4e96c..d14560e10 100644 --- a/frontend/drupal/modules/simpletest/tests/ajax_test.info +++ b/frontend/drupal/modules/simpletest/tests/ajax_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/batch_test.info b/frontend/drupal/modules/simpletest/tests/batch_test.info index 8878b8a52..747535cc2 100644 --- a/frontend/drupal/modules/simpletest/tests/batch_test.info +++ b/frontend/drupal/modules/simpletest/tests/batch_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/boot_test_1.info b/frontend/drupal/modules/simpletest/tests/boot_test_1.info index d7a7cc3b2..13593e665 100644 --- a/frontend/drupal/modules/simpletest/tests/boot_test_1.info +++ b/frontend/drupal/modules/simpletest/tests/boot_test_1.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/boot_test_2.info b/frontend/drupal/modules/simpletest/tests/boot_test_2.info index 00a205616..89c7c31d0 100644 --- a/frontend/drupal/modules/simpletest/tests/boot_test_2.info +++ b/frontend/drupal/modules/simpletest/tests/boot_test_2.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/common.test b/frontend/drupal/modules/simpletest/tests/common.test index f5b85bad0..b22c4a6f5 100644 --- a/frontend/drupal/modules/simpletest/tests/common.test +++ b/frontend/drupal/modules/simpletest/tests/common.test @@ -1484,8 +1484,8 @@ class JavaScriptTestCase extends DrupalWebTestCase { */ function testAddSetting() { $javascript = drupal_add_js(array('drupal' => 'rocks', 'dries' => 280342800), 'setting'); - $this->assertEqual(280342800, $javascript['settings']['data'][2]['dries'], 'JavaScript setting is set correctly.'); - $this->assertEqual('rocks', $javascript['settings']['data'][2]['drupal'], 'The other JavaScript setting is set correctly.'); + $this->assertEqual(280342800, $javascript['settings']['data'][3]['dries'], 'JavaScript setting is set correctly.'); + $this->assertEqual('rocks', $javascript['settings']['data'][3]['drupal'], 'The other JavaScript setting is set correctly.'); } /** @@ -1923,6 +1923,18 @@ class JavaScriptTestCase extends DrupalWebTestCase { $this->assertRaw(drupal_get_path('module', 'node') . '/node.js?' . $query_string, 'Query string was appended correctly to js.'); } + /** + * Tests that the set_has_js_cookie variable is reflected in Drupal.settings. + */ + function testSetHasJsCookie() { + $this->drupalGet(''); + $this->assertRaw('"setHasJsCookie":0', 'setHasJsCookie set to 0 by default.'); + + variable_set('set_has_js_cookie', TRUE); + $this->drupalGet(''); + $this->assertRaw('"setHasJsCookie":1', 'setHasJsCookie set to 1 when set_has_js_cookie is set to TRUE.'); + } + /** * Resets static variables related to adding JavaScript to a page. */ @@ -3297,3 +3309,48 @@ class BlockInterestCohortTest extends DrupalWebTestCase { } } + +/** + * Test for drupal_add_html_head_link(). + */ +class DrupalAddHtmlHeadLinkTest extends DrupalWebTestCase { + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'Add HTML head link', + 'description' => 'Test for drupal_add_html_head_link().', + 'group' => 'System', + ); + } + + /** + * {@inheritdoc} + */ + function setUp() { + parent::setUp('common_test'); + } + + /** + * Tests drupal_add_html_head_link(). + */ + function testDrupalAddHtmlHeadLink() { + $this->drupalGet('common-test/html_head_link'); + $expected_link_header = implode(',', array( + '; rel="alternate"', + '; hreflang="nl"; rel="alternate"', + '; hreflang="de"; rel="alternate"', + '; hreflang="en"; rel="alternate"', + )); + $this->assertEqual($this->drupalGetHeader('Link'), $expected_link_header); + + // Check that duplicate alternate URLs with different hreflangs are allowed. + $test_link = $this->xpath('//head/link[@rel="alternate"][@href="/foo/bar"]'); + $this->assertEqual(count($test_link), 2, 'Duplicate alternate URLs are allowed.'); + // Check that link element attributes are HTML-encoded. + $this->assertRaw(''); + } + +} diff --git a/frontend/drupal/modules/simpletest/tests/common_test.info b/frontend/drupal/modules/simpletest/tests/common_test.info index 15d76e061..2a657192a 100644 --- a/frontend/drupal/modules/simpletest/tests/common_test.info +++ b/frontend/drupal/modules/simpletest/tests/common_test.info @@ -7,7 +7,7 @@ stylesheets[all][] = common_test.css stylesheets[print][] = common_test.print.css hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/common_test.module b/frontend/drupal/modules/simpletest/tests/common_test.module index d7b97bc89..863d6b02f 100644 --- a/frontend/drupal/modules/simpletest/tests/common_test.module +++ b/frontend/drupal/modules/simpletest/tests/common_test.module @@ -64,6 +64,12 @@ function common_test_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); + $items['common-test/html_head_link'] = array( + 'title' => 'Test HTML head link', + 'page callback' => 'common_test_html_head_link', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); return $items; } @@ -314,3 +320,33 @@ function existing_permissions_policy_header() { drupal_add_http_header('Permissions-Policy', 'geolocation=()'); print __FUNCTION__; } + +/** + * Page callback. + */ +function common_test_html_head_link() { + drupal_add_html_head_link(array( + 'href' => '/foo?bar=baz', + 'rel' => 'alternate', + ), TRUE); + drupal_add_html_head_link(array( + 'href' => '/not-added-to-http-headers', + 'rel' => 'alternate', + ), FALSE); + drupal_add_html_head_link(array( + 'href' => '/foo/bar', + 'hreflang' => 'nl', + 'rel' => 'alternate', + ), TRUE); + drupal_add_html_head_link(array( + 'href' => '/foo/bar', + 'hreflang' => 'de', + 'rel' => 'alternate', + ), TRUE); + drupal_add_html_head_link(array( + 'href' => '/foo?bar=baz&baz=false', + 'hreflang' => 'en', + 'rel' => 'alternate', + ), TRUE); + return ''; +} diff --git a/frontend/drupal/modules/simpletest/tests/common_test_cron_helper.info b/frontend/drupal/modules/simpletest/tests/common_test_cron_helper.info index 4db789dec..cc245d148 100644 --- a/frontend/drupal/modules/simpletest/tests/common_test_cron_helper.info +++ b/frontend/drupal/modules/simpletest/tests/common_test_cron_helper.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/database_test.info b/frontend/drupal/modules/simpletest/tests/database_test.info index bb4d83700..083996317 100644 --- a/frontend/drupal/modules/simpletest/tests/database_test.info +++ b/frontend/drupal/modules/simpletest/tests/database_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/database_test.install b/frontend/drupal/modules/simpletest/tests/database_test.install index 44ed5ee0a..6d9ba8334 100644 --- a/frontend/drupal/modules/simpletest/tests/database_test.install +++ b/frontend/drupal/modules/simpletest/tests/database_test.install @@ -236,5 +236,7 @@ function database_test_schema() { 'primary key' => array('id'), ); + $schema['TEST_UPPERCASE'] = $schema['test']; + return $schema; } diff --git a/frontend/drupal/modules/simpletest/tests/database_test.test b/frontend/drupal/modules/simpletest/tests/database_test.test index 0f0d2c320..1f4c2b078 100644 --- a/frontend/drupal/modules/simpletest/tests/database_test.test +++ b/frontend/drupal/modules/simpletest/tests/database_test.test @@ -27,6 +27,7 @@ class DatabaseTestCase extends DrupalWebTestCase { $schema['test_one_blob'] = drupal_get_schema('test_one_blob'); $schema['test_two_blobs'] = drupal_get_schema('test_two_blobs'); $schema['test_task'] = drupal_get_schema('test_task'); + $schema['TEST_UPPERCASE'] = drupal_get_schema('TEST_UPPERCASE'); $this->installTables($schema); @@ -876,20 +877,6 @@ class DatabaseUpdateTestCase extends DatabaseTestCase { ->execute(); $this->assertIdentical($num_rows, 3, 'Number of affected rows are returned.'); } - - /** - * Confirm that we can update the primary key of a record successfully. - */ - function testPrimaryKeyUpdate() { - $num_updated = db_update('test') - ->fields(array('id' => 42, 'name' => 'John')) - ->condition('id', 1) - ->execute(); - $this->assertIdentical($num_updated, 1, 'Updated 1 record.'); - - $saved_name= db_query('SELECT name FROM {test} WHERE id = :id', array(':id' => 42))->fetchField(); - $this->assertIdentical($saved_name, 'John', 'Updated primary key successfully.'); - } } /** @@ -3463,6 +3450,67 @@ class DatabaseQueryTestCase extends DatabaseTestCase { ->fetchField(); $this->assertFalse($result, 'SQL injection attempt did not result in a row being inserted in the database table.'); } + + /** + * Tests SQL injection via condition operator. + */ + public function testConditionOperatorArgumentsSQLInjection() { + + $injection = "IS NOT NULL); INSERT INTO {test} (name) VALUES ('test12345678'); -- "; + try { + $result = db_select('test', 't') + ->fields('t') + ->condition('name', 1, $injection) + ->execute(); + $this->fail('Should not be able to attempt SQL injection via condition operator.'); + } + catch (InvalidQueryConditionOperatorException $e) { + $this->pass('SQL injection attempt via condition arguments should result in a database exception.'); + } + + // Test that the insert query that was used in the SQL injection attempt did + // not result in a row being inserted in the database. + $result = db_select('test') + ->condition('name', 'test12345678') + ->countQuery() + ->execute() + ->fetchField(); + $this->assertFalse($result, 'SQL injection attempt did not result in a row being inserted in the database table.'); + + // Attempt SQLi via union query with no unsafe characters. + db_insert('test') + ->fields(array('name' => '123456')) + ->execute(); + + $injection = "= 1 UNION ALL SELECT password FROM user WHERE uid ="; + try { + $result = db_select('test', 't') + ->fields('t', array('name', 'name')) + ->condition('name', 1, $injection) + ->execute(); + $this->fail('Should not be able to attempt SQL injection via operator.'); + } + catch (InvalidQueryConditionOperatorException $e) { + $this->pass('SQL injection attempt via condition arguments should result in a database exception.'); + } + + // Attempt SQLi via union query - uppercase tablename. + db_insert('TEST_UPPERCASE') + ->fields(array('name' => 'secrets')) + ->execute(); + + $injection = "IS NOT NULL) UNION ALL SELECT name FROM {TEST_UPPERCASE} -- "; + try { + $result = db_select('test', 't') + ->fields('t', array('name')) + ->condition('name', 1, $injection) + ->execute(); + $this->fail('Should not be able to attempt SQL injection via operator.'); + } + catch (InvalidQueryConditionOperatorException $e) { + $this->pass('SQL injection attempt via condition arguments should result in a database exception.'); + } + } } /** diff --git a/frontend/drupal/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info b/frontend/drupal/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info index 6081961fa..95e0edc60 100644 --- a/frontend/drupal/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info +++ b/frontend/drupal/modules/simpletest/tests/drupal_autoload_test/drupal_autoload_test.info @@ -7,7 +7,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/frontend/drupal/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info index 210c5e7ba..f1e3f56fe 100644 --- a/frontend/drupal/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info +++ b/frontend/drupal/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/frontend/drupal/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info index d5e2724ae..eefb0495d 100644 --- a/frontend/drupal/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info +++ b/frontend/drupal/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/entity_cache_test.info b/frontend/drupal/modules/simpletest/tests/entity_cache_test.info index 2e06c3511..1b1f5b560 100644 --- a/frontend/drupal/modules/simpletest/tests/entity_cache_test.info +++ b/frontend/drupal/modules/simpletest/tests/entity_cache_test.info @@ -6,7 +6,7 @@ core = 7.x dependencies[] = entity_cache_test_dependency hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/entity_cache_test_dependency.info b/frontend/drupal/modules/simpletest/tests/entity_cache_test_dependency.info index b471c08e8..f008bb06d 100644 --- a/frontend/drupal/modules/simpletest/tests/entity_cache_test_dependency.info +++ b/frontend/drupal/modules/simpletest/tests/entity_cache_test_dependency.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/entity_crud_hook_test.info b/frontend/drupal/modules/simpletest/tests/entity_crud_hook_test.info index 1d6a4d0b8..25bf994f4 100644 --- a/frontend/drupal/modules/simpletest/tests/entity_crud_hook_test.info +++ b/frontend/drupal/modules/simpletest/tests/entity_crud_hook_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/entity_query_access_test.info b/frontend/drupal/modules/simpletest/tests/entity_query_access_test.info index d05746fa4..9d480a8e2 100644 --- a/frontend/drupal/modules/simpletest/tests/entity_query_access_test.info +++ b/frontend/drupal/modules/simpletest/tests/entity_query_access_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/error_test.info b/frontend/drupal/modules/simpletest/tests/error_test.info index fc36a6402..fdf781810 100644 --- a/frontend/drupal/modules/simpletest/tests/error_test.info +++ b/frontend/drupal/modules/simpletest/tests/error_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/file.test b/frontend/drupal/modules/simpletest/tests/file.test index 57b315fb0..ff8cb2f7a 100644 --- a/frontend/drupal/modules/simpletest/tests/file.test +++ b/frontend/drupal/modules/simpletest/tests/file.test @@ -108,6 +108,7 @@ class FileTestCase extends DrupalWebTestCase { // Mask out all but the last three octets. $actual_mode = fileperms($filepath) & 0777; + $expected_mode = $expected_mode & 0777; // PHP on Windows has limited support for file permissions. Usually each of // "user", "group" and "other" use one octal digit (3 bits) to represent the @@ -143,6 +144,7 @@ class FileTestCase extends DrupalWebTestCase { // Mask out all but the last three octets. $actual_mode = fileperms($directory) & 0777; + $expected_mode = $expected_mode & 0777; // PHP on Windows has limited support for file permissions. Usually each of // "user", "group" and "other" use one octal digit (3 bits) to represent the @@ -1055,6 +1057,39 @@ class FileDirectoryTest extends FileTestCase { ); } + /** + * Test local directory handling functions. + */ + function testFileCheckLocalDirectoryHandling() { + $directory = file_default_scheme() . '://'; + + // Check a new recursively created local directory for correct file system + // permissions. + $parent = $this->randomName(); + $child = $this->randomName(); + + // Files directory already exists. + $this->assertTrue(is_dir($directory), 'Files directory already exists.', 'File'); + // Make files directory writable only. + $old_mode = fileperms($directory); + + // Create the directories. + $parent_path = $directory . DIRECTORY_SEPARATOR . $parent; + $child_path = $parent_path . DIRECTORY_SEPARATOR . $child; + $this->assertTrue(drupal_mkdir($child_path, 0775, TRUE), 'No error reported when creating new local directories.', 'File'); + + // Ensure new directories also exist. + $this->assertTrue(is_dir($parent_path), 'New parent directory actually exists.', 'File'); + $this->assertTrue(is_dir($child_path), 'New child directory actually exists.', 'File'); + + // Check that new directory permissions were set properly. + $this->assertDirectoryPermissions($parent_path, 0775); + $this->assertDirectoryPermissions($child_path, 0775); + + // Check that existing directory permissions were not modified. + $this->assertDirectoryPermissions($directory, $old_mode); + } + /** * Test directory handling functions. */ diff --git a/frontend/drupal/modules/simpletest/tests/file_test.info b/frontend/drupal/modules/simpletest/tests/file_test.info index 96621d7b2..618ef4a85 100644 --- a/frontend/drupal/modules/simpletest/tests/file_test.info +++ b/frontend/drupal/modules/simpletest/tests/file_test.info @@ -6,7 +6,7 @@ core = 7.x files[] = file_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/filetransfer.test b/frontend/drupal/modules/simpletest/tests/filetransfer.test index 905d23cab..617e6cc02 100644 --- a/frontend/drupal/modules/simpletest/tests/filetransfer.test +++ b/frontend/drupal/modules/simpletest/tests/filetransfer.test @@ -114,7 +114,7 @@ class TestFileTransfer extends FileTransfer { $parts = explode(':', $this->hostname); $port = (count($parts) == 2) ? $parts[1] : $this->port; $this->connection = new MockTestConnection(); - $this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/"; + $this->connection->connectionString = 'test://' . urlencode((string) $this->username) . ':' . urlencode((string) $this->password) . "@$this->host:$this->port/"; } function copyFileJailed($source, $destination) { diff --git a/frontend/drupal/modules/simpletest/tests/filter_test.info b/frontend/drupal/modules/simpletest/tests/filter_test.info index 9b89aecda..236228bee 100644 --- a/frontend/drupal/modules/simpletest/tests/filter_test.info +++ b/frontend/drupal/modules/simpletest/tests/filter_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/form_test.info b/frontend/drupal/modules/simpletest/tests/form_test.info index 06353b5ef..20ab25594 100644 --- a/frontend/drupal/modules/simpletest/tests/form_test.info +++ b/frontend/drupal/modules/simpletest/tests/form_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/image_test.info b/frontend/drupal/modules/simpletest/tests/image_test.info index 79781caec..b64dc91ba 100644 --- a/frontend/drupal/modules/simpletest/tests/image_test.info +++ b/frontend/drupal/modules/simpletest/tests/image_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/menu.test b/frontend/drupal/modules/simpletest/tests/menu.test index f5d7d290f..daea9f09e 100644 --- a/frontend/drupal/modules/simpletest/tests/menu.test +++ b/frontend/drupal/modules/simpletest/tests/menu.test @@ -1738,3 +1738,41 @@ class MenuTrailTestCase extends MenuWebTestCase { } } } + +/** + * Tests value integrity. + */ +class MenuDataIntegrityTestCase extends MenuWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Menu item array integrity', + 'description' => 'Tests the values passed on to menu items array.', + 'group' => 'Menu', + ); + } + + /** + * Tests for null/casting weight parameter. + */ + public function testNullMenuWeight() { + $base_options = array( + 'link_title' => 'Menu link test', + 'module' => 'menu_test', + 'menu_name' => 'menu_test', + 'weight' => NULL, + 'link_path' => 'menu-test/parent', + ); + + try { + menu_link_save($base_options); + } + catch (PDOException $exception) { + $this->fail('Menu weight is not being cast properly.'); + return; + } + + $this->pass('Menu weight is being cast properly.'); + } + +} diff --git a/frontend/drupal/modules/simpletest/tests/menu_test.info b/frontend/drupal/modules/simpletest/tests/menu_test.info index 9cc4d67cd..4ec0d46b1 100644 --- a/frontend/drupal/modules/simpletest/tests/menu_test.info +++ b/frontend/drupal/modules/simpletest/tests/menu_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/module_test.info b/frontend/drupal/modules/simpletest/tests/module_test.info index c7ff0786b..93e5e0800 100644 --- a/frontend/drupal/modules/simpletest/tests/module_test.info +++ b/frontend/drupal/modules/simpletest/tests/module_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/pager.test b/frontend/drupal/modules/simpletest/tests/pager.test index 432edbf45..1a0047216 100644 --- a/frontend/drupal/modules/simpletest/tests/pager.test +++ b/frontend/drupal/modules/simpletest/tests/pager.test @@ -169,6 +169,6 @@ class PagerFunctionalWebTestCase extends DrupalWebTestCase { if (!isset($message)) { $message = "Class .$class not found."; } - $this->assertTrue(strpos($element['class'], $class) === FALSE, $message); + $this->assertTrue(strpos((string) $element['class'], $class) === FALSE, $message); } } diff --git a/frontend/drupal/modules/simpletest/tests/path_test.info b/frontend/drupal/modules/simpletest/tests/path_test.info index 26016c248..1bf1a546f 100644 --- a/frontend/drupal/modules/simpletest/tests/path_test.info +++ b/frontend/drupal/modules/simpletest/tests/path_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/psr_0_test/psr_0_test.info b/frontend/drupal/modules/simpletest/tests/psr_0_test/psr_0_test.info index 2261da817..d4bf76438 100644 --- a/frontend/drupal/modules/simpletest/tests/psr_0_test/psr_0_test.info +++ b/frontend/drupal/modules/simpletest/tests/psr_0_test/psr_0_test.info @@ -5,7 +5,7 @@ core = 7.x hidden = TRUE package = Testing -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/psr_4_test/psr_4_test.info b/frontend/drupal/modules/simpletest/tests/psr_4_test/psr_4_test.info index e7be9bba1..bcce9e557 100644 --- a/frontend/drupal/modules/simpletest/tests/psr_4_test/psr_4_test.info +++ b/frontend/drupal/modules/simpletest/tests/psr_4_test/psr_4_test.info @@ -5,7 +5,7 @@ core = 7.x hidden = TRUE package = Testing -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/requirements1_test.info b/frontend/drupal/modules/simpletest/tests/requirements1_test.info index 718bb0d51..84ddf0791 100644 --- a/frontend/drupal/modules/simpletest/tests/requirements1_test.info +++ b/frontend/drupal/modules/simpletest/tests/requirements1_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/requirements2_test.info b/frontend/drupal/modules/simpletest/tests/requirements2_test.info index a81d18a81..7653288df 100644 --- a/frontend/drupal/modules/simpletest/tests/requirements2_test.info +++ b/frontend/drupal/modules/simpletest/tests/requirements2_test.info @@ -7,7 +7,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/session.test b/frontend/drupal/modules/simpletest/tests/session.test index 5632d44e4..b309546f1 100644 --- a/frontend/drupal/modules/simpletest/tests/session.test +++ b/frontend/drupal/modules/simpletest/tests/session.test @@ -773,3 +773,123 @@ class SessionHttpsTestCase extends DrupalWebTestCase { } } +/** + * Unit tests for session handling. + */ +class SessionUnitTestCase extends DrupalUnitTestCase { + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'Session unit tests', + 'description' => 'Test session handling functionality.', + 'group' => 'Session', + ); + } + + function testCookieDomain() { + $tests = array( + array('example.com', '.example.com'), + array('www.example.com', '.www.example.com'), + array('subdomain.example.com', '.subdomain.example.com'), + ); + + foreach ($tests as $test) { + $this->assertEqual(_drupal_get_cookie_domain($test[0]), $test[1], 'Correct $cookie_domain for host ' . $test[0]); + } + } + + /** + * Unit test drupal_settings_initialize(). + */ + function testSessionInitialization() { + global $base_url, $cookie_domain; + + $tests = array( + array( + 'http_host' => 'example.com', + 'script_name' => '/index.php', + 'session_name' => 'SESSa379a6f6eeafb9a55e378c118034e275', + 'base_url' => 'http://example.com', + 'cookie_domain' => '.example.com', + ), + array( + 'http_host' => 'example.com', + 'script_name' => '/foo/index.php', + 'session_name' => 'SESS76f699faa11e8fbe9a70d933651df90f', + 'base_url' => 'http://example.com/foo', + 'cookie_domain' => '.example.com', + ), + array( + 'http_host' => 'one.two.example.com', + 'script_name' => '/index.php', + 'session_name' => 'SESSc0cc73483118b575693f5c255faeb739', + 'base_url' => 'http://one.two.example.com', + 'cookie_domain' => '.one.two.example.com', + ), + array( + 'http_host' => 'www.sub.example.com', + 'script_name' => '/index.php', + 'session_name' => 'SESSdc70980beaa5d571d3c9785cf9246c96', + 'base_url' => 'http://www.sub.example.com', + 'cookie_domain' => '.www.sub.example.com', + ), + array( + 'http_host' => 'example.com', + 'script_name' => '/foo/bar/index.php', + 'session_name' => 'SESSdbf7edcf4f2656b247021ceb4752f7f9', + 'base_url' => 'http://example.com/foo/bar', + 'cookie_domain' => '.example.com', + ), + array( + 'http_host' => 'www.sub.example.com', + 'script_name' => '/baz/index.php', + 'session_name' => 'SESS63543f965940db9e8a79801aa6d52423', + 'base_url' => 'http://www.sub.example.com/baz', + 'cookie_domain' => '.www.sub.example.com', + ), + array( + 'http_host' => 'sub.example.com', + 'script_name' => '/index.php', + 'session_name' => 'SESS005c4a974d8b94af421206f9ef34efeb', + 'base_url' => 'http://sub.example.com', + 'cookie_domain' => '.sub.example.com', + ), + array( + 'http_host' => 'www.example.com', + 'script_name' => '/index.php', + 'session_name' => 'SESS0e9f0e2600e4d8f26827597c5e324261', + 'base_url' => 'http://www.example.com', + 'cookie_domain' => '.www.example.com', + ), + array( + 'http_host' => 'www.example.com', + 'script_name' => '/foo/index.php', + 'session_name' => 'SESS0ddd0afc0bece848c840cdcd7b8ed9c9', + 'base_url' => 'http://www.example.com/foo', + 'cookie_domain' => '.www.example.com', + ), + array( + 'http_host' => 'www.example.com', + 'script_name' => '/bar/index.php', + 'session_name' => 'SESS22f2cd08599536cb4363fcd09e29d264', + 'base_url' => 'http://www.example.com/bar', + 'cookie_domain' => '.www.example.com', + ), + ); + + foreach ($tests as $test) { + $_SERVER['HTTP_HOST'] = $test['http_host']; + $_SERVER['SCRIPT_NAME'] = $test['script_name']; + $cookie_domain = NULL; + $base_url = NULL; + drupal_settings_initialize(); + $this->assertEqual(session_name(), $test['session_name'], 'Correct session_name for ' . $test['http_host'] . $test['script_name']); + $this->assertEqual($base_url, $test['base_url'], 'Correct base_url for ' . $test['http_host'] . $test['script_name']); + $this->assertEqual($cookie_domain, $test['cookie_domain'], 'Correct cookie_domain for ' . $test['http_host'] . $test['script_name']); + } + + } +} diff --git a/frontend/drupal/modules/simpletest/tests/session_test.info b/frontend/drupal/modules/simpletest/tests/session_test.info index ed5293711..266f16efa 100644 --- a/frontend/drupal/modules/simpletest/tests/session_test.info +++ b/frontend/drupal/modules/simpletest/tests/session_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_dependencies_test.info b/frontend/drupal/modules/simpletest/tests/system_dependencies_test.info index 842e8614b..2fd173b3d 100644 --- a/frontend/drupal/modules/simpletest/tests/system_dependencies_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_dependencies_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE dependencies[] = _missing_dependency -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info b/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info index cb5b3bf4f..4dc52740c 100644 --- a/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE dependencies[] = system_incompatible_core_version_test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_test.info b/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_test.info index 0fa176aad..0e133868a 100644 --- a/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_incompatible_core_version_test.info @@ -5,7 +5,7 @@ version = VERSION core = 5.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info b/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info index be40aa489..9f6a97f82 100644 --- a/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info @@ -7,7 +7,7 @@ hidden = TRUE ; 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 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_test.info b/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_test.info index 36d47a7fc..653498b24 100644 --- a/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_incompatible_module_version_test.info @@ -5,7 +5,7 @@ version = 1.0 core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_project_namespace_test.info b/frontend/drupal/modules/simpletest/tests/system_project_namespace_test.info index 3a384c43a..eb67a61af 100644 --- a/frontend/drupal/modules/simpletest/tests/system_project_namespace_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_project_namespace_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE dependencies[] = drupal:filter -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_test.info b/frontend/drupal/modules/simpletest/tests/system_test.info index 9f301f1b1..e5f3994d9 100644 --- a/frontend/drupal/modules/simpletest/tests/system_test.info +++ b/frontend/drupal/modules/simpletest/tests/system_test.info @@ -6,7 +6,7 @@ core = 7.x files[] = system_test.module hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/system_test.module b/frontend/drupal/modules/simpletest/tests/system_test.module index fef539adb..7e4f2c489 100644 --- a/frontend/drupal/modules/simpletest/tests/system_test.module +++ b/frontend/drupal/modules/simpletest/tests/system_test.module @@ -566,6 +566,6 @@ function system_test_module_implements_alter(&$implementations, $hook) { $group = $implementations['system_test']; unset($implementations['system_test']); $count = count($implementations); - $implementations = array_merge(array_slice($implementations, 0, $count / 2, TRUE), array('system_test' => $group), array_slice($implementations, $count / 2, NULL, TRUE)); + $implementations = array_merge(array_slice($implementations, 0, (int) ($count / 2), TRUE), array('system_test' => $group), array_slice($implementations, (int) ($count / 2), NULL, TRUE)); } } diff --git a/frontend/drupal/modules/simpletest/tests/taxonomy_test.info b/frontend/drupal/modules/simpletest/tests/taxonomy_test.info index ec0b3924a..5bb621489 100644 --- a/frontend/drupal/modules/simpletest/tests/taxonomy_test.info +++ b/frontend/drupal/modules/simpletest/tests/taxonomy_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE dependencies[] = taxonomy -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/theme_test.info b/frontend/drupal/modules/simpletest/tests/theme_test.info index f58f8030c..5902514c3 100644 --- a/frontend/drupal/modules/simpletest/tests/theme_test.info +++ b/frontend/drupal/modules/simpletest/tests/theme_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info b/frontend/drupal/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info index 1139b44c0..3337f6c98 100644 --- a/frontend/drupal/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info +++ b/frontend/drupal/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info @@ -6,7 +6,7 @@ hidden = TRUE settings[basetheme_only] = base theme value settings[subtheme_override] = base theme value -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info b/frontend/drupal/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info index 6ee0b5143..33fc1c965 100644 --- a/frontend/drupal/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info +++ b/frontend/drupal/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info @@ -6,7 +6,7 @@ hidden = TRUE settings[subtheme_override] = subtheme value -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/themes/test_theme/test_theme.info b/frontend/drupal/modules/simpletest/tests/themes/test_theme/test_theme.info index 75a4e88bd..5c94628e4 100644 --- a/frontend/drupal/modules/simpletest/tests/themes/test_theme/test_theme.info +++ b/frontend/drupal/modules/simpletest/tests/themes/test_theme/test_theme.info @@ -17,7 +17,7 @@ stylesheets[all][] = system.base.css settings[theme_test_setting] = default value -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info b/frontend/drupal/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info index e70e191d2..e5334d07f 100644 --- a/frontend/drupal/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info +++ b/frontend/drupal/modules/simpletest/tests/themes/test_theme_nyan_cat/test_theme_nyan_cat.info @@ -4,7 +4,7 @@ core = 7.x hidden = TRUE engine = nyan_cat -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/update_script_test.info b/frontend/drupal/modules/simpletest/tests/update_script_test.info index e98ed2585..69fafa74b 100644 --- a/frontend/drupal/modules/simpletest/tests/update_script_test.info +++ b/frontend/drupal/modules/simpletest/tests/update_script_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/update_test_1.info b/frontend/drupal/modules/simpletest/tests/update_test_1.info index 3ab697a06..283832a14 100644 --- a/frontend/drupal/modules/simpletest/tests/update_test_1.info +++ b/frontend/drupal/modules/simpletest/tests/update_test_1.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/update_test_2.info b/frontend/drupal/modules/simpletest/tests/update_test_2.info index 3ab697a06..283832a14 100644 --- a/frontend/drupal/modules/simpletest/tests/update_test_2.info +++ b/frontend/drupal/modules/simpletest/tests/update_test_2.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/update_test_3.info b/frontend/drupal/modules/simpletest/tests/update_test_3.info index 3ab697a06..283832a14 100644 --- a/frontend/drupal/modules/simpletest/tests/update_test_3.info +++ b/frontend/drupal/modules/simpletest/tests/update_test_3.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/url_alter_test.info b/frontend/drupal/modules/simpletest/tests/url_alter_test.info index 80cb93327..d80fe2e0f 100644 --- a/frontend/drupal/modules/simpletest/tests/url_alter_test.info +++ b/frontend/drupal/modules/simpletest/tests/url_alter_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/simpletest/tests/url_alter_test.module b/frontend/drupal/modules/simpletest/tests/url_alter_test.module index 9287ff523..bdc3167a8 100644 --- a/frontend/drupal/modules/simpletest/tests/url_alter_test.module +++ b/frontend/drupal/modules/simpletest/tests/url_alter_test.module @@ -57,7 +57,7 @@ function url_alter_test_url_inbound_alter(&$path, $original_path, $path_language */ function url_alter_test_url_outbound_alter(&$path, &$options, $original_path) { // Rewrite user/uid to user/username. - if (preg_match('!^user/([0-9]+)(/.*)?!', $path, $matches)) { + if (preg_match('!^user/([0-9]+)(/.*)?!', (string) $path, $matches)) { if ($account = user_load($matches[1])) { $matches += array(2 => ''); $path = 'user/' . $account->name . $matches[2]; @@ -65,7 +65,7 @@ function url_alter_test_url_outbound_alter(&$path, &$options, $original_path) { } // Rewrite forum/ to community/. - if ($path == 'forum' || strpos($path, 'forum/') === 0) { + if ($path == 'forum' || strpos((string) $path, 'forum/') === 0) { $path = 'community' . substr($path, 5); } } diff --git a/frontend/drupal/modules/simpletest/tests/xmlrpc_test.info b/frontend/drupal/modules/simpletest/tests/xmlrpc_test.info index c64924176..1a8c80d71 100644 --- a/frontend/drupal/modules/simpletest/tests/xmlrpc_test.info +++ b/frontend/drupal/modules/simpletest/tests/xmlrpc_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/statistics/statistics.info b/frontend/drupal/modules/statistics/statistics.info index ebe6be5b0..a0757cae6 100644 --- a/frontend/drupal/modules/statistics/statistics.info +++ b/frontend/drupal/modules/statistics/statistics.info @@ -6,7 +6,7 @@ core = 7.x files[] = statistics.test configure = admin/config/system/statistics -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/syslog/syslog.info b/frontend/drupal/modules/syslog/syslog.info index 90b55f9b5..0e7c4a3e9 100644 --- a/frontend/drupal/modules/syslog/syslog.info +++ b/frontend/drupal/modules/syslog/syslog.info @@ -6,7 +6,7 @@ core = 7.x files[] = syslog.test configure = admin/config/development/logging -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/syslog/syslog.module b/frontend/drupal/modules/syslog/syslog.module index af3eb0a0f..32193a18d 100644 --- a/frontend/drupal/modules/syslog/syslog.module +++ b/frontend/drupal/modules/syslog/syslog.module @@ -111,8 +111,8 @@ function syslog_watchdog(array $log_entry) { '!request_uri' => $log_entry['request_uri'], '!referer' => $log_entry['referer'], '!uid' => $log_entry['uid'], - '!link' => strip_tags($log_entry['link']), - '!message' => strip_tags(!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables'])), + '!link' => strip_tags((string) $log_entry['link']), + '!message' => strip_tags((string) (!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables']))), )); syslog($log_entry['severity'], $message); diff --git a/frontend/drupal/modules/system/image.gd.inc b/frontend/drupal/modules/system/image.gd.inc index 3d0797e42..bcc02cf06 100644 --- a/frontend/drupal/modules/system/image.gd.inc +++ b/frontend/drupal/modules/system/image.gd.inc @@ -204,9 +204,11 @@ function image_gd_rotate(stdClass $image, $degrees, $background = NULL) { * @see image_crop() */ function image_gd_crop(stdClass $image, $x, $y, $width, $height) { + $width = (int) $width; + $height = (int) $height; $res = image_gd_create_tmp($image, $width, $height); - if (!imagecopyresampled($res, $image->resource, 0, 0, $x, $y, $width, $height, $width, $height)) { + if (!imagecopyresampled($res, $image->resource, 0, 0, (int) $x, (int) $y, $width, $height, $width, $height)) { return FALSE; } diff --git a/frontend/drupal/modules/system/system.info b/frontend/drupal/modules/system/system.info index 30f827ff4..a5c60e3df 100644 --- a/frontend/drupal/modules/system/system.info +++ b/frontend/drupal/modules/system/system.info @@ -12,7 +12,7 @@ files[] = system.test required = TRUE configure = admin/config/system -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/system/system.install b/frontend/drupal/modules/system/system.install index 01b0af474..4f3b28991 100644 --- a/frontend/drupal/modules/system/system.install +++ b/frontend/drupal/modules/system/system.install @@ -236,20 +236,36 @@ function system_requirements($phase) { // Test settings.php file writability if ($phase == 'runtime') { - $conf_dir = drupal_verify_install_file(conf_path(), FILE_NOT_WRITABLE, 'dir'); - $conf_file = drupal_verify_install_file(conf_path() . '/settings.php', FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE); - if (!$conf_dir || !$conf_file) { + $conf_errors = array(); + // Allow system administrators to ignore permissions hardening for the site + // directory. This allows additional files in the site directory to be + // updated when they are managed in a version control system. + $skip_permissions_hardening = variable_get('skip_permissions_hardening', FALSE); + + if ($skip_permissions_hardening) { + $error_value = t('Protection disabled'); + // If permissions hardening is disabled, then only show a warning for a + // writable file, as a reminder, rather than an error. + $file_protection_severity = REQUIREMENT_WARNING; + } + else { + $error_value = t('Not protected'); + // In normal operation, writable files or directories are an error. + $file_protection_severity = REQUIREMENT_ERROR; + if (!drupal_verify_install_file(conf_path(), FILE_NOT_WRITABLE, 'dir')) { + $conf_errors[] = $t('The directory %file is not protected from modifications and poses a security risk. You must change the directory\'s permissions to be non-writable. ', array('%file' => conf_path())); + } + } + if (!drupal_verify_install_file(conf_path() . '/settings.php', FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE, 'file', !$skip_permissions_hardening)) { + $conf_errors[] = $t('The file %file is not protected from modifications and poses a security risk. You must change the file\'s permissions to be non-writable.', array('%file' => conf_path() . '/settings.php')); + } + + if (!empty($conf_errors)) { $requirements['settings.php'] = array( - 'value' => $t('Not protected'), - 'severity' => REQUIREMENT_ERROR, - 'description' => '', + 'value' => $error_value, + 'severity' => $file_protection_severity, + 'description' => implode('
', $conf_errors), ); - if (!$conf_dir) { - $requirements['settings.php']['description'] .= $t('The directory %file is not protected from modifications and poses a security risk. You must change the directory\'s permissions to be non-writable. ', array('%file' => conf_path())); - } - if (!$conf_file) { - $requirements['settings.php']['description'] .= $t('The file %file is not protected from modifications and poses a security risk. You must change the file\'s permissions to be non-writable.', array('%file' => conf_path() . '/settings.php')); - } } else { $requirements['settings.php'] = array( @@ -522,7 +538,7 @@ function system_requirements($phase) { // Warning for httpoxy on IIS with affected PHP versions. // @see https://www.drupal.org/node/2783079 - if (strpos($software, 'Microsoft-IIS') !== FALSE && (version_compare(PHP_VERSION, '5.5.38', '<') + if (strpos((string) $software, 'Microsoft-IIS') !== FALSE && (version_compare(PHP_VERSION, '5.5.38', '<') || (version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '5.6.24', '<')) || (version_compare(PHP_VERSION, '7.0.0', '>=') && version_compare(PHP_VERSION, '7.0.9', '<')) )) { diff --git a/frontend/drupal/modules/system/system.module b/frontend/drupal/modules/system/system.module index 02785ef57..4d909dac7 100644 --- a/frontend/drupal/modules/system/system.module +++ b/frontend/drupal/modules/system/system.module @@ -1328,6 +1328,7 @@ function system_library() { 'version' => '1.8.7', 'js' => array( 'misc/ui/jquery.ui.datepicker.min.js' => array(), + 'misc/ui/jquery.ui.datepicker-1.13.0-backport.js' => array(), ), 'css' => array( 'misc/ui/jquery.ui.datepicker.css' => array(), @@ -1341,7 +1342,8 @@ function system_library() { 'website' => 'http://jqueryui.com/demos/dialog/', 'version' => '1.8.7', 'js' => array( - 'misc/ui/jquery.ui.dialog.min.js' => array(), + 'misc/ui/jquery.ui.dialog.min.js' => array(), + 'misc/ui/jquery.ui.dialog-1.13.0-backport.js' => array(), ), 'css' => array( 'misc/ui/jquery.ui.dialog.css' => array(), @@ -1397,6 +1399,7 @@ function system_library() { 'version' => '1.8.7', 'js' => array( 'misc/ui/jquery.ui.position.min.js' => array(), + 'misc/ui/jquery.ui.position-1.13.0-backport.js' => array(), ), ); $libraries['ui.progressbar'] = array( diff --git a/frontend/drupal/modules/system/system.tar.inc b/frontend/drupal/modules/system/system.tar.inc index 7a0719e58..0b26f9cb7 100644 --- a/frontend/drupal/modules/system/system.tar.inc +++ b/frontend/drupal/modules/system/system.tar.inc @@ -41,7 +41,7 @@ /** * Note on Drupal 7 porting. - * This file origin is Tar.php, release 1.4.9 (stable) with some code + * This file origin is Tar.php, release 1.4.14 (stable) with some code * from PEAR.php, release 1.10.10 (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. @@ -792,7 +792,7 @@ class Archive_Tar */ public function setIgnoreList($list) { - $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); + $list = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); $regexp = '#/' . join('$|/', $list) . '#'; $this->setIgnoreRegexp($regexp); } @@ -1336,7 +1336,7 @@ class Archive_Tar while (($v_buffer = fread($v_file, $this->buffer_length)) != '') { $buffer_length = strlen("$v_buffer"); if ($buffer_length != $this->buffer_length) { - $pack_size = ((int)($buffer_length / 512) + 1) * 512; + $pack_size = ((int)($buffer_length / 512) + ($buffer_length % 512 !== 0 ? 1 : 0)) * 512; $pack_format = sprintf('a%d', $pack_size); } else { $pack_format = sprintf('a%d', $this->buffer_length); @@ -1465,11 +1465,13 @@ class Archive_Tar $userinfo = posix_getpwuid($v_info[4]); $groupinfo = posix_getgrgid($v_info[5]); - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; - } else { - $v_uname = ''; - $v_gname = ''; + if (isset($userinfo['name'])) { + $v_uname = $userinfo['name']; + } + + if (isset($groupinfo['name'])) { + $v_gname = $groupinfo['name']; + } } $v_devmajor = ''; @@ -1578,8 +1580,13 @@ class Archive_Tar $userinfo = posix_getpwuid($p_uid); $groupinfo = posix_getgrgid($p_gid); - $v_uname = $userinfo['name']; - $v_gname = $groupinfo['name']; + if ($userinfo === false || $groupinfo === false) { + $v_uname = ''; + $v_gname = ''; + } else { + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } } else { $v_uname = ''; $v_gname = ''; @@ -2178,14 +2185,6 @@ class Archive_Tar } } } elseif ($v_header['typeflag'] == "2") { - if (strpos(realpath(dirname($v_header['link'])), realpath($p_path)) !== 0) { - $this->_error( - 'Out-of-path file extraction {' - . $v_header['filename'] . ' --> ' . - $v_header['link'] . '}' - ); - return false; - } if (!$p_symlinks) { $this->_warning('Symbolic links are not allowed. ' . 'Unable to extract {' @@ -2193,6 +2192,40 @@ class Archive_Tar ); return false; } + $absolute_link = FALSE; + $link_depth = 0; + if (strpos($v_header['link'], "/") === 0 || strpos($v_header['link'], ':') !== FALSE) { + $absolute_link = TRUE; + } + else { + $s_filename = preg_replace('@^' . preg_quote($p_path) . '@', "", $v_header['filename']); + $s_linkname = str_replace('\\', '/', $v_header['link']); + foreach (explode("/", $s_filename) as $dir) { + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== "." ) { + $link_depth++; + } + } + foreach (explode("/", $s_linkname) as $dir){ + if ($link_depth <= 0) { + break; + } + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== ".") { + $link_depth++; + } + } + } + if ($absolute_link || $link_depth <= 0) { + $this->_error( + 'Out-of-path file extraction {' + . $v_header['filename'] . ' --> ' . + $v_header['link'] . '}' + ); + return false; + } if (@file_exists($v_header['filename'])) { @drupal_unlink($v_header['filename']); } diff --git a/frontend/drupal/modules/system/system.test b/frontend/drupal/modules/system/system.test index 45c6648c4..865a0e6b8 100644 --- a/frontend/drupal/modules/system/system.test +++ b/frontend/drupal/modules/system/system.test @@ -3096,3 +3096,98 @@ class ConfirmFormTest extends DrupalWebTestCase { return $this->assertTrue(isset($links[0]), $message, $group); } } + +/** + * Test case for Archiver classes. + * + * Cannot be a DrupalUnitTestCase as it requires access to the db and files. + */ +class SystemArchiverTest extends DrupalWebTestCase +{ + + public static function getInfo() + { + return array( + 'name' => 'Archiver tests', + 'description' => 'Test the Archiver classes.', + 'group' => 'System', + ); + } + + /** + * Tests interacting with a tarball archive. + */ + public function testArchiverTarball() { + $src_tarball = DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/tests/system_test_archive.tar.gz'; + $tmp = file_directory_temp(); + $tarball = $tmp . '/' . basename($src_tarball); + file_unmanaged_copy($src_tarball, $tarball); + try { + $archiver = archiver_get_archiver($tarball); + } + catch (Exception $e) { + // The file's not there (this is not part of the test). + $this->assertTrue(FALSE, $e); + return; + } + + // Test \ArchiverTar::listContents + $listing = $archiver->listContents(); + $this->assertEqual(count($listing), 4, 'Tarball listing has 4 entries.'); + $this->assertTrue((strpos(implode(',', $listing), 'tarball.module') !== FALSE), 'Tarball listing includes tarball.module'); + + // Test \ArchiverTar::extract + $extract_dir = file_directory_temp() . '/testArchiverTarball'; + $archiver->extract($extract_dir); + $this->assertTrue(file_exists($extract_dir . '/system_test_archive/test.txt'), 'test.txt extracted from tarball'); + $this->assertEqual(count(glob($extract_dir . '/system_test_archive/*')), 3, '3 files extracted from tarball'); + + // Test \ArchiverTar::add + $extra_file = DRUPAL_ROOT . '/misc/druplicon.png'; + $archiver->add($extra_file); + $new_listing = $archiver->listContents(); + // \ArchiverTar::add probably should not add the new file with its absolute + // path. However that's how \Archive_Tar::add works. If we wanted to modify + // the file path within the archive, we could call \Archive_Tar::addModify + // directly and use its additional parameters. That could be done using + // \ArchiverTar::getArchive like in _testArchiverOutOfPath() which calls + // \Archive_Tar::extract directly. + $this->assertTrue(in_array($extra_file, $new_listing), 'Druplicon added to tarball'); + } + + /** + * Tests out-of-path extraction protection. + */ + public function testArchiverOutOfPath() { + $this->_testArchiverOutOfPath('system_test_archive_rel.tar', 'Relative out-of-path extraction caught'); + $this->_testArchiverOutOfPath('system_test_archive_abs.tgz', 'Absolute out-of-path extraction caught'); + } + + /** + * Helper to test out-of-path extraction protection. + */ + public function _testArchiverOutOfPath($archive, $message) { + $src_tarball = DRUPAL_ROOT . '/modules/system/tests/' . $archive; + $tarball = file_directory_temp() . '/' . $archive; + file_unmanaged_copy($src_tarball, $tarball); + try { + $archiver = archiver_get_archiver($tarball); + } catch (Exception $e) { + // The file's not there (this is not part of the test). + $this->assertTrue(FALSE, $e); + return; + } + + $extract_dir = file_directory_temp() . '/testArchiverTarball'; + $caught_exception = FALSE; + try { + // Drupal's \ArchiverTar::extract() doesn't support symlinks, so we have + // to access the underlying Archive_Tar object. + $archiver->getArchive()->extract($extract_dir, FALSE, TRUE); + } + catch (Exception $e) { + $caught_exception = (strpos($e->getMessage(), 'Out-of-path file extraction') !== FALSE); + } + $this->assertTrue($caught_exception, $message); + } +} diff --git a/frontend/drupal/modules/system/tests/cron_queue_test.info b/frontend/drupal/modules/system/tests/cron_queue_test.info index 116a661c8..4c8642371 100644 --- a/frontend/drupal/modules/system/tests/cron_queue_test.info +++ b/frontend/drupal/modules/system/tests/cron_queue_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/system/tests/system_cron_test.info b/frontend/drupal/modules/system/tests/system_cron_test.info index 1f1e03d88..472b92757 100644 --- a/frontend/drupal/modules/system/tests/system_cron_test.info +++ b/frontend/drupal/modules/system/tests/system_cron_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/system/tests/system_test_archive.tar.gz b/frontend/drupal/modules/system/tests/system_test_archive.tar.gz new file mode 100644 index 000000000..603baea01 Binary files /dev/null and b/frontend/drupal/modules/system/tests/system_test_archive.tar.gz differ diff --git a/frontend/drupal/modules/system/tests/system_test_archive_abs.tgz b/frontend/drupal/modules/system/tests/system_test_archive_abs.tgz new file mode 100644 index 000000000..bf4a3ff41 Binary files /dev/null and b/frontend/drupal/modules/system/tests/system_test_archive_abs.tgz differ diff --git a/frontend/drupal/modules/system/tests/system_test_archive_rel.tar b/frontend/drupal/modules/system/tests/system_test_archive_rel.tar new file mode 100644 index 000000000..b528d681a Binary files /dev/null and b/frontend/drupal/modules/system/tests/system_test_archive_rel.tar differ diff --git a/frontend/drupal/modules/taxonomy/taxonomy.admin.inc b/frontend/drupal/modules/taxonomy/taxonomy.admin.inc index 828fde0ab..b44128ed8 100644 --- a/frontend/drupal/modules/taxonomy/taxonomy.admin.inc +++ b/frontend/drupal/modules/taxonomy/taxonomy.admin.inc @@ -826,8 +826,8 @@ function taxonomy_form_term_submit($form, &$form_state) { break; } - $current_parent_count = count($form_state['values']['parent']); - $previous_parent_count = count($form['#term']['parent']); + $current_parent_count = empty($form_state['values']['parent']) ? 0 : count((array) $form_state['values']['parent']); + $previous_parent_count = empty($form['#term']['parent']) ? 0 : count((array) $form['#term']['parent']); // Root doesn't count if it's the only parent. if ($current_parent_count == 1 && isset($form_state['values']['parent'][0])) { $current_parent_count = 0; diff --git a/frontend/drupal/modules/taxonomy/taxonomy.info b/frontend/drupal/modules/taxonomy/taxonomy.info index ad773aeca..09357b36b 100644 --- a/frontend/drupal/modules/taxonomy/taxonomy.info +++ b/frontend/drupal/modules/taxonomy/taxonomy.info @@ -8,7 +8,7 @@ files[] = taxonomy.module files[] = taxonomy.test configure = admin/structure/taxonomy -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/toolbar/toolbar.info b/frontend/drupal/modules/toolbar/toolbar.info index 7944ab7b4..b5076dfec 100644 --- a/frontend/drupal/modules/toolbar/toolbar.info +++ b/frontend/drupal/modules/toolbar/toolbar.info @@ -4,7 +4,7 @@ core = 7.x package = Core version = VERSION -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/tracker/tracker.info b/frontend/drupal/modules/tracker/tracker.info index 6463bc776..72b711d7c 100644 --- a/frontend/drupal/modules/tracker/tracker.info +++ b/frontend/drupal/modules/tracker/tracker.info @@ -6,7 +6,7 @@ version = VERSION core = 7.x files[] = tracker.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/translation/tests/translation_test.info b/frontend/drupal/modules/translation/tests/translation_test.info index 6b5b43dfa..e7aa47e9f 100644 --- a/frontend/drupal/modules/translation/tests/translation_test.info +++ b/frontend/drupal/modules/translation/tests/translation_test.info @@ -5,7 +5,7 @@ package = Testing version = VERSION hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/translation/translation.info b/frontend/drupal/modules/translation/translation.info index fe2d19d5b..4cb333c06 100644 --- a/frontend/drupal/modules/translation/translation.info +++ b/frontend/drupal/modules/translation/translation.info @@ -6,7 +6,7 @@ version = VERSION core = 7.x files[] = translation.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/trigger/tests/trigger_test.info b/frontend/drupal/modules/trigger/tests/trigger_test.info index acc680c29..919f7e842 100644 --- a/frontend/drupal/modules/trigger/tests/trigger_test.info +++ b/frontend/drupal/modules/trigger/tests/trigger_test.info @@ -4,7 +4,7 @@ package = Testing core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/trigger/trigger.info b/frontend/drupal/modules/trigger/trigger.info index 5c7013c9d..e6375f3bf 100644 --- a/frontend/drupal/modules/trigger/trigger.info +++ b/frontend/drupal/modules/trigger/trigger.info @@ -6,7 +6,7 @@ core = 7.x files[] = trigger.test configure = admin/structure/trigger -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/aaa_update_test.info b/frontend/drupal/modules/update/tests/aaa_update_test.info index 1e163cc99..cf38d77c4 100644 --- a/frontend/drupal/modules/update/tests/aaa_update_test.info +++ b/frontend/drupal/modules/update/tests/aaa_update_test.info @@ -4,7 +4,7 @@ package = Testing core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/bbb_update_test.info b/frontend/drupal/modules/update/tests/bbb_update_test.info index c4fd1dbef..2591ee5d3 100644 --- a/frontend/drupal/modules/update/tests/bbb_update_test.info +++ b/frontend/drupal/modules/update/tests/bbb_update_test.info @@ -4,7 +4,7 @@ package = Testing core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/ccc_update_test.info b/frontend/drupal/modules/update/tests/ccc_update_test.info index 2e9cffb69..13ebd345f 100644 --- a/frontend/drupal/modules/update/tests/ccc_update_test.info +++ b/frontend/drupal/modules/update/tests/ccc_update_test.info @@ -4,7 +4,7 @@ package = Testing core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info b/frontend/drupal/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info index 90d9ce3ea..23ee2233b 100644 --- a/frontend/drupal/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info +++ b/frontend/drupal/modules/update/tests/themes/update_test_admintheme/update_test_admintheme.info @@ -3,7 +3,7 @@ description = Test theme which is used as admin theme. core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info b/frontend/drupal/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info index 3b92ff10f..575c4a010 100644 --- a/frontend/drupal/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info +++ b/frontend/drupal/modules/update/tests/themes/update_test_basetheme/update_test_basetheme.info @@ -3,7 +3,7 @@ description = Test theme which acts as a base theme for other test subthemes. core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info b/frontend/drupal/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info index c2e05c860..c82d886c2 100644 --- a/frontend/drupal/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info +++ b/frontend/drupal/modules/update/tests/themes/update_test_subtheme/update_test_subtheme.info @@ -4,7 +4,7 @@ core = 7.x base theme = update_test_basetheme hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/tests/update_test.info b/frontend/drupal/modules/update/tests/update_test.info index 47ca4dda2..4e8374908 100644 --- a/frontend/drupal/modules/update/tests/update_test.info +++ b/frontend/drupal/modules/update/tests/update_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/update/update.info b/frontend/drupal/modules/update/update.info index d564fbdae..5a4981bb2 100644 --- a/frontend/drupal/modules/update/update.info +++ b/frontend/drupal/modules/update/update.info @@ -6,7 +6,7 @@ core = 7.x files[] = update.test configure = admin/reports/updates/settings -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/user/tests/user_flood_test.info b/frontend/drupal/modules/user/tests/user_flood_test.info index 5b25a920a..b79ceb6bb 100644 --- a/frontend/drupal/modules/user/tests/user_flood_test.info +++ b/frontend/drupal/modules/user/tests/user_flood_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/user/tests/user_form_test.info b/frontend/drupal/modules/user/tests/user_form_test.info index 1dabda93d..9eeb5f569 100644 --- a/frontend/drupal/modules/user/tests/user_form_test.info +++ b/frontend/drupal/modules/user/tests/user_form_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/user/tests/user_session_test.info b/frontend/drupal/modules/user/tests/user_session_test.info index 781643bf4..1b4454d81 100644 --- a/frontend/drupal/modules/user/tests/user_session_test.info +++ b/frontend/drupal/modules/user/tests/user_session_test.info @@ -5,7 +5,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/user/user.admin.inc b/frontend/drupal/modules/user/user.admin.inc index 0db7efb1a..21281b9b8 100644 --- a/frontend/drupal/modules/user/user.admin.inc +++ b/frontend/drupal/modules/user/user.admin.inc @@ -167,6 +167,7 @@ function user_admin_account() { 'status' => array('data' => t('Status'), 'field' => 'u.status'), 'roles' => array('data' => t('Roles')), 'member_for' => array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'), + 'changed' => array('data' => t('Last changed'), 'field' => 'u.changed', 'sort' => 'desc'), 'access' => array('data' => t('Last access'), 'field' => 'u.access'), 'operations' => array('data' => t('Operations')), ); @@ -180,7 +181,7 @@ function user_admin_account() { $query = $query->extend('PagerDefault')->extend('TableSort'); $query - ->fields('u', array('uid', 'name', 'status', 'created', 'access')) + ->fields('u', array('uid', 'name', 'status', 'created', 'changed', 'access')) ->limit(50) ->orderByHeader($header) ->setCountQuery($count_query); @@ -226,6 +227,7 @@ function user_admin_account() { 'status' => $status[$account->status], 'roles' => theme('item_list', array('items' => $users_roles)), 'member_for' => format_interval(REQUEST_TIME - $account->created), + 'changed' => t('@time ago', array('@time' => format_interval(REQUEST_TIME - $account->changed))), 'access' => $account->access ? t('@time ago', array('@time' => format_interval(REQUEST_TIME - $account->access))) : t('never'), 'operations' => array('data' => array('#type' => 'link', '#title' => t('edit'), '#href' => "user/$account->uid/edit", '#options' => array('query' => $destination))), ); @@ -437,6 +439,18 @@ function user_admin_settings() { '#description' => t("This text is displayed at the picture upload form in addition to the default guidelines. It's useful for helping or instructing your users."), ); + $form['privacy'] = array( + '#type' => 'fieldset', + '#title' => t('Privacy'), + ); + $form['privacy']['user_password_reset_text'] = array( + '#type' => 'textarea', + '#title' => t('Password reset text'), + '#default_value' => variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')), + '#description' => t('The text that appears when a user successfully submits the password reset form. Due to privacy concerns, it should not contain any information about previously registered users. %identifier will be replaced with what the user entered into the form field.'), + '#required' => TRUE, + ); + $form['email_title'] = array( '#type' => 'item', '#title' => t('E-mails'), diff --git a/frontend/drupal/modules/user/user.info b/frontend/drupal/modules/user/user.info index 221d12acb..9bde360d3 100644 --- a/frontend/drupal/modules/user/user.info +++ b/frontend/drupal/modules/user/user.info @@ -9,7 +9,7 @@ required = TRUE configure = admin/config/people stylesheets[all][] = user.css -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/modules/user/user.install b/frontend/drupal/modules/user/user.install index 7a74766a1..f965179b8 100644 --- a/frontend/drupal/modules/user/user.install +++ b/frontend/drupal/modules/user/user.install @@ -182,6 +182,12 @@ function user_schema() { 'default' => 0, 'description' => 'Timestamp for when user was created.', ), + 'changed' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Timestamp for when user was changed.', + ), 'access' => array( 'type' => 'int', 'not null' => TRUE, @@ -238,6 +244,7 @@ function user_schema() { 'indexes' => array( 'access' => array('access'), 'created' => array('created'), + 'changed' => array('changed'), 'mail' => array('mail'), 'picture' => array('picture'), ), @@ -312,6 +319,7 @@ function user_install() { 'name' => 'placeholder-for-uid-1', 'mail' => 'placeholder-for-uid-1', 'created' => REQUEST_TIME, + 'changed' => REQUEST_TIME, 'status' => 1, 'data' => NULL, )) @@ -922,6 +930,29 @@ function user_update_7019() { db_add_index('authmap', 'uid_module', array('uid', 'module')); } } + +/** + * Add changed field to users table. + */ +function user_update_7020() { + $spec = array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Timestamp for when user was changed.', + ); + $keys = array( + 'indexes' => array( + 'changed' => array('changed'), + ), + ); + db_add_field('users', 'changed', $spec, $keys); + + // Set the initial value for existing users + db_update('users') + ->expression('changed', 'created') + ->execute(); +} /** * @} End of "addtogroup updates-7.x-extra". */ diff --git a/frontend/drupal/modules/user/user.module b/frontend/drupal/modules/user/user.module index dfa05978c..84e7bd6e6 100644 --- a/frontend/drupal/modules/user/user.module +++ b/frontend/drupal/modules/user/user.module @@ -304,7 +304,7 @@ class UserController extends DrupalDefaultEntityController { $picture_fids = array(); foreach ($queried_users as $key => $record) { $picture_fids[] = $record->picture; - $queried_users[$key]->data = unserialize($record->data); + $queried_users[$key]->data = unserialize((string) $record->data); $queried_users[$key]->roles = array(); if ($record->uid) { $queried_users[$record->uid]->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; @@ -506,6 +506,8 @@ function user_save($account, $edit = array(), $category = 'account') { // Do not allow 'uid' to be changed. $account->uid = $account->original->uid; + // Save current time as last changed time. + $account->changed = REQUEST_TIME; // Save changes to the user table. $success = drupal_write_record('users', $account, 'uid'); // Restore the picture object. @@ -577,6 +579,8 @@ function user_save($account, $edit = array(), $category = 'account') { if (!isset($account->created)) { $account->created = REQUEST_TIME; } + // Save current time as last changed time. + $account->changed = REQUEST_TIME; $success = drupal_write_record('users', $account); if ($success === FALSE) { // On a failed INSERT some other existing user's uid may be returned. diff --git a/frontend/drupal/modules/user/user.pages.inc b/frontend/drupal/modules/user/user.pages.inc index 937f7a31e..1266bbfb5 100644 --- a/frontend/drupal/modules/user/user.pages.inc +++ b/frontend/drupal/modules/user/user.pages.inc @@ -107,9 +107,6 @@ function user_pass_validate($form, &$form_state) { flood_register_event('pass_reset_user', $user_pass_reset_user_window, $identifier); form_set_value(array('#parents' => array('account')), $account, $form_state); } - else { - form_set_error('name', t('Sorry, %name is not recognized as a user name or an e-mail address.', array('%name' => $name))); - } } /** @@ -120,14 +117,21 @@ function user_pass_validate($form, &$form_state) { function user_pass_submit($form, &$form_state) { global $language; - $account = $form_state['values']['account']; - // Mail one time login URL and instructions using current language. - $mail = _user_mail_notify('password_reset', $account, $language); - if (!empty($mail)) { - watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)); - drupal_set_message(t('Further instructions have been sent to your e-mail address.')); + $name = $form_state['values']['name']; + if (isset($form_state['values']['account'])) { + $account = $form_state['values']['account']; + // Mail one time login URL and instructions using current language. + $mail = _user_mail_notify('password_reset', $account, $language); + if (!empty($mail)) { + watchdog('user', 'Password reset instructions mailed to %name at %email.', array('%name' => $account->name, '%email' => $account->mail)); + } + } + else { + watchdog('user', 'Password reset form was submitted with an unknown or inactive account: %name.', array('%name' => $name)); } + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + drupal_set_message(format_string($password_reset_text, array('%identifier' => $name))); $form_state['redirect'] = 'user'; return; } diff --git a/frontend/drupal/modules/user/user.test b/frontend/drupal/modules/user/user.test index ec2f90d6f..1c3155924 100644 --- a/frontend/drupal/modules/user/user.test +++ b/frontend/drupal/modules/user/user.test @@ -164,6 +164,7 @@ class UserRegistrationTestCase extends DrupalWebTestCase { $this->assertEqual($new_user->theme, '', 'Correct theme field.'); $this->assertEqual($new_user->signature, '', 'Correct signature field.'); $this->assertTrue(($new_user->created > REQUEST_TIME - 20 ), 'Correct creation time.'); + $this->assertEqual($new_user->changed, $new_user->created, 'Correct changed time.'); $this->assertEqual($new_user->status, variable_get('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL) == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); $this->assertEqual($new_user->timezone, variable_get('date_default_timezone'), 'Correct time zone field.'); $this->assertEqual($new_user->language, '', 'Correct language field.'); @@ -534,11 +535,20 @@ class UserPasswordResetTestCase extends DrupalWebTestCase { // Attempt to reset password. $edit = array('name' => $account->name); $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset. - $this->assertText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message displayed.'); + // Ensure the correct message is shown for a valid user name. + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + $this->assertRaw(format_string($password_reset_text, array('%identifier' => $account->name)), 'Password reset instructions mailed message displayed for a valid user.'); + // Ensure that flood control was not triggered. $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by single password reset.'); + // Ensure the correct message is shown for a non-existent user name. + $name = $this->randomName(); + $edit = array('name' => $name); + $this->drupalPost('user/password', $edit, t('E-mail new password')); + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + $this->assertRaw(format_string($password_reset_text, array('%identifier' => $name)), 'Password reset instructions mailed message displayed for a non-existent user.'); + // Create an image field to enable an Ajax request on the user profile page. $field = array( 'field_name' => 'field_avatar', @@ -619,7 +629,8 @@ class UserPasswordResetTestCase extends DrupalWebTestCase { for ($i = 0; $i < 2; $i++) { $this->drupalPost('user/password', $edit, t('E-mail new password')); // Confirm the password reset. - $this->assertText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message displayed.'); + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + $this->assertRaw(format_string($password_reset_text, array('%identifier' => $account->name)), 'Password reset instructions mailed message displayed.'); // Ensure that flood control was not triggered. $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); } @@ -636,7 +647,8 @@ class UserPasswordResetTestCase extends DrupalWebTestCase { for ($i = 0; $i < 2; $i++) { $this->drupalPost('user/password', $edit, t('E-mail new password')); // Confirm the password reset. - $this->assertText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message displayed.'); + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + $this->assertRaw(format_string($password_reset_text, array('%identifier' => $account->name)), 'Password reset instructions mailed message displayed.'); // Ensure that flood control was not triggered. $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); } @@ -661,9 +673,9 @@ class UserPasswordResetTestCase extends DrupalWebTestCase { $name = $this->randomName(); $edit = array('name' => $name); $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset was not blocked. Note that @name is used - // instead of %name as assertText() works with plain text not HTML. - $this->assertText(t('Sorry, @name is not recognized as a user name or an e-mail address.', array('@name' => $name)), 'User name not recognized message displayed.'); + // Confirm the password reset was not blocked. + $password_reset_text = variable_get('user_password_reset_text', t('If %identifier is a valid account, an email will be sent with instructions to reset your password.')); + $this->assertRaw(format_string($password_reset_text, array('%identifier' => $name)), 'Password reset instructions mailed message displayed.'); // Ensure that flood control was not triggered. $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); } @@ -1358,7 +1370,7 @@ class UserPictureTestCase extends DrupalWebTestCase { $this->assertRaw($text, 'File size cited as reason for failure.'); // Check if file is not uploaded. - $this->assertFalse(is_file($pic_path), 'File was not uploaded.'); + $this->assertFalse(is_file((string) $pic_path), 'File was not uploaded.'); } } @@ -2532,6 +2544,8 @@ class UserTokenReplaceTestCase extends DrupalWebTestCase { $tests['[user:last-login:short]'] = format_date($account->login, 'short', '', NULL, $language->language); $tests['[user:created]'] = format_date($account->created, 'medium', '', NULL, $language->language); $tests['[user:created:short]'] = format_date($account->created, 'short', '', NULL, $language->language); + $tests['[user:changed]'] = format_date($account->changed, 'medium', '', NULL, $language->language); + $tests['[user:changed:short]'] = format_date($account->changed, 'short', '', NULL, $language->language); $tests['[current-user:name]'] = check_plain(format_username($global_account)); // Test to make sure that we generated something for each token. diff --git a/frontend/drupal/modules/user/user.tokens.inc b/frontend/drupal/modules/user/user.tokens.inc index 8dcea4b59..55acfbf5c 100644 --- a/frontend/drupal/modules/user/user.tokens.inc +++ b/frontend/drupal/modules/user/user.tokens.inc @@ -52,6 +52,12 @@ function user_token_info() { 'type' => 'date', ); + $user['changed'] = array( + 'name' => t("Changed"), + 'description' => t("The date the user account was changed."), + 'type' => 'date', + ); + return array( 'types' => $types, 'tokens' => array('user' => $user), @@ -110,6 +116,11 @@ function user_tokens($type, $tokens, array $data = array(), array $options = arr // In the case of user_presave the created date may not yet be set. $replacements[$original] = !empty($account->created) ? format_date($account->created, 'medium', '', NULL, $language_code) : t('not yet created'); break; + + case 'changed': + // In the case of user_presave the created date may not yet be set. + $replacements[$original] = !empty($account->changed) ? format_date($account->changed, 'medium', '', NULL, $language_code) : t('not yet created'); + break; } } @@ -120,6 +131,10 @@ function user_tokens($type, $tokens, array $data = array(), array $options = arr if ($registered_tokens = token_find_with_prefix($tokens, 'created')) { $replacements += token_generate('date', $registered_tokens, array('date' => $account->created), $options); } + + if ($changed_tokens = token_find_with_prefix($tokens, 'changed')) { + $replacements += token_generate('date', $changed_tokens, array('date' => $account->changed), $options); + } } if ($type == 'current-user') { diff --git a/frontend/drupal/profiles/minimal/minimal.info b/frontend/drupal/profiles/minimal/minimal.info index 5c58ad0d1..2abe7a118 100644 --- a/frontend/drupal/profiles/minimal/minimal.info +++ b/frontend/drupal/profiles/minimal/minimal.info @@ -5,7 +5,7 @@ core = 7.x dependencies[] = block dependencies[] = dblog -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/profiles/standard/standard.info b/frontend/drupal/profiles/standard/standard.info index c95011aef..2e2b14f46 100644 --- a/frontend/drupal/profiles/standard/standard.info +++ b/frontend/drupal/profiles/standard/standard.info @@ -24,7 +24,7 @@ dependencies[] = field_ui dependencies[] = file dependencies[] = rdf -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/profiles/standard/standard.install b/frontend/drupal/profiles/standard/standard.install index ae34eafaf..158c4eaaa 100644 --- a/frontend/drupal/profiles/standard/standard.install +++ b/frontend/drupal/profiles/standard/standard.install @@ -356,7 +356,7 @@ function standard_install() { 'required' => FALSE, 'settings' => array( - 'file_directory' => 'field/image', + 'file_directory' => '[date:custom:Y]-[date:custom:m]', 'file_extensions' => 'png gif jpg jpeg', 'max_filesize' => '', 'max_resolution' => '', diff --git a/frontend/drupal/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/frontend/drupal/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info index 127a9ca1b..179065f96 100644 --- a/frontend/drupal/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info +++ b/frontend/drupal/profiles/testing/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info @@ -6,7 +6,7 @@ core = 7.x hidden = TRUE files[] = drupal_system_listing_compatible_test.test -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/frontend/drupal/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info index b7f6cc052..e2f37af95 100644 --- a/frontend/drupal/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info +++ b/frontend/drupal/profiles/testing/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info @@ -8,7 +8,7 @@ version = VERSION core = 6.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/profiles/testing/testing.info b/frontend/drupal/profiles/testing/testing.info index 173e2b21e..f4b72b531 100644 --- a/frontend/drupal/profiles/testing/testing.info +++ b/frontend/drupal/profiles/testing/testing.info @@ -4,7 +4,7 @@ version = VERSION core = 7.x hidden = TRUE -; Information added by Drupal.org packaging script on 2021-06-02 -version = "7.81" +; Information added by Drupal.org packaging script on 2022-01-19 +version = "7.87" project = "drupal" -datestamp = "1622633234" +datestamp = "1642633901" diff --git a/frontend/drupal/scripts/run-tests.sh b/frontend/drupal/scripts/run-tests.sh index b18fd142a..ff0eab5ab 100755 --- a/frontend/drupal/scripts/run-tests.sh +++ b/frontend/drupal/scripts/run-tests.sh @@ -142,6 +142,8 @@ All arguments are long options. --all Run all available tests. --class Run tests identified by specific class names, instead of group names. + A specific test method can be added, for example, + 'UserAccountLinksUnitTests::testDisabledAccountLink'. --file Run tests identified by specific file names, instead of group names. Specify the path and the extension (i.e. 'modules/user/user.test'). @@ -408,10 +410,19 @@ function simpletest_script_run_one_test($test_id, $test_class) { simpletest_classloader_register(); - $test = new $test_class($test_id); + if (strpos($test_class, '::') > 0) { + list($class_name, $method) = explode('::', $test_class, 2); + $methods = array($method); + } + else { + $class_name = $test_class; + // Use empty array to run all the test methods. + $methods = array(); + } + $test = new $class_name($test_id); $test->useSetupInstallationCache = !empty($args['cache']); $test->useSetupModulesCache = !empty($args['cache-modules']); - $test->run(); + $test->run($methods); $info = $test->getInfo(); $had_fails = (isset($test->results['#fail']) && $test->results['#fail'] > 0); @@ -477,8 +488,16 @@ function simpletest_script_get_test_list() { // Check for valid class names. $test_list = array(); foreach ($args['test_names'] as $test_class) { - if (class_exists($test_class)) { - $test_list[] = $test_class; + list($class_name, $method) = explode('::', $test_class, 2); + if (class_exists($class_name)) { + if (empty($method) || method_exists($class_name, $method)) { + $test_list[] = $test_class; + } else { + $all_methods = get_class_methods($class_name); + simpletest_script_print_error('Test method not found: ' . $test_class); + simpletest_script_print_alternatives($method, $all_methods, 6); + exit(1); + } } else { $groups = simpletest_test_get_all(); @@ -486,8 +505,8 @@ function simpletest_script_get_test_list() { foreach ($groups as $group) { $all_classes = array_merge($all_classes, array_keys($group)); } - simpletest_script_print_error('Test class not found: ' . $test_class); - simpletest_script_print_alternatives($test_class, $all_classes, 6); + simpletest_script_print_error('Test class not found: ' . $class_name); + simpletest_script_print_alternatives($class_name, $all_classes, 6); exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); } } @@ -597,9 +616,14 @@ function simpletest_script_reporter_init() { } else { echo "Tests to be run:\n"; - foreach ($test_list as $class_name) { - $info = call_user_func(array($class_name, 'getInfo')); - echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n"; + foreach ($test_list as $test_name) { + if (strpos($test_name, '::') > 0) { + list($test_class, $method) = explode('::', $test_name, 2); + $info = call_user_func(array($test_class, 'getInfo')); + } else { + $info = call_user_func(array($test_name, 'getInfo')); + } + echo " - " . $info['name'] . ' (' . $test_name . ')' . "\n"; } echo "\n"; } diff --git a/frontend/drupal/sites/all/libraries/ckeditor/CHANGES.md b/frontend/drupal/sites/all/libraries/ckeditor/CHANGES.md index 72c579805..1e7b8e8d8 100644 --- a/frontend/drupal/sites/all/libraries/ckeditor/CHANGES.md +++ b/frontend/drupal/sites/all/libraries/ckeditor/CHANGES.md @@ -1,1219 +1,2117 @@ -CKEditor 4 Changelog -==================== - -## CKEditor 4.6.2 - -New Features: - -* [#16733](http://dev.ckeditor.com/ticket/16733): Added a new pastel color palette for the [Color Button](http://ckeditor.com/addon/colorbutton) plugin and a new [`config.colorButton_colorsPerRow`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_colorsPerRow) configuration option for setting the number of rows in the color selector. -* [#16752](http://dev.ckeditor.com/ticket/16752): Added a new Azerbaijani localization. Thanks to the [Azerbaijani language team](https://www.transifex.com/ckeditor/teams/11143/az/)! -* [#13818](http://dev.ckeditor.com/ticket/13818): It is now possible to group [Widget](http://ckeditor.com/addon/widget) [style definitions](http://docs.ckeditor.com/#!/guide/dev_styles-section-widget-styles), so applying one style disables the other. - -Fixed Issues: - -* [#13446](http://dev.ckeditor.com/ticket/13446): [Chrome] Fixed: It is possible to type in an unfocused inline editor. -* [#14856](http://dev.ckeditor.com/ticket/14856): Fixed: [Font size and font family](http://ckeditor.com/addon/font) reset each other when modified at certain positions. -* [#16745](http://dev.ckeditor.com/ticket/16745): [Edge] Fixed: List items are lost when [pasted from Word](http://ckeditor.com/addon/pastefromword). -* [#16682](http://dev.ckeditor.com/ticket/16682): [Edge] Fixed: A list gets [pasted from Word](http://ckeditor.com/addon/pastefromword) as a set of paragraphs. Added the [`config.pasteFromWord_heuristicsEdgeList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWord_heuristicsEdgeList) configuration option. -* [#10373](http://dev.ckeditor.com/ticket/10373): Fixed: Context menu items can be dragged into the editor. -* [#16728](http://dev.ckeditor.com/ticket/16728): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Quirks Mode. -* [#16795](http://dev.ckeditor.com/ticket/16795): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Compatibility Mode. -* [#16675](http://dev.ckeditor.com/ticket/16675): Fixed: Styles applied with [Copy Formatting](http://ckeditor.com/addon/copyformatting) to a single table cell are applied to the whole table. -* [#16753](http://dev.ckeditor.com/ticket/16753): Fixed: [`element.setSize`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-setSize) sets incorrect editor dimensions if the border width is represented as a fraction of pixels. -* [#16705](http://dev.ckeditor.com/ticket/16705): [Firefox] Fixed: Unable to paste images as Base64 strings when using [Clipboard](http://ckeditor.com/addon/clipboard). -* [#14869](http://dev.ckeditor.com/ticket/14869): Fixed: JavaScript error is thrown when trying to use [Find](http://ckeditor.com/addon/find) in a [`
`-based editor](http://ckeditor.com/addon/divarea). - -## CKEditor 4.6.1 - -New Features: - -* [#16639](http://dev.ckeditor.com/ticket/16639): The `callback` parameter in the [CKEDITOR.ajax.post](http://docs.ckeditor.com/#!/api/CKEDITOR.ajax-method-post) method became optional. - -Fixed Issues: - -* [#11064](http://dev.ckeditor.com/ticket/11064): [Blink, WebKit] Fixed: Cannot select all editor content when a widget or a non-editable element is the first or last element of the content. Also fixes this issue in the [Select All](http://ckeditor.com/addon/selectall) plugin. -* [#14755](http://dev.ckeditor.com/ticket/14755): [Blink, WebKit, IE8] Fixed: Browser hangs when a table is inserted in the place of a selected list with an empty last item. -* [#16624](http://dev.ckeditor.com/ticket/16624): Fixed: Improved the [Color Button](http://ckeditor.com/addon/colorbutton) plugin which will now normalize the CSS `background` property if it only contains a color value. This fixes missing background colors when using [Paste from Word](http://ckeditor.com/addon/pastefromword). -* [#16600](http://dev.ckeditor.com/ticket/16600): [Blink, WebKit] Fixed: Error thrown occasionally by an uninitialized editable for multiple CKEditor instances on the same page. - -## CKEditor 4.6 - -New Features: - -* [#14569](http://dev.ckeditor.com/ticket/14569): Added a new, flat, default CKEditor skin called [Moono-Lisa](http://ckeditor.com/addon/moono-lisa). Refreshed default colors available in the [Color Button](http://ckeditor.com/addon/colorbutton) plugin ([Text Color and Background Color](http://docs.ckeditor.com/#!/guide/dev_colorbutton) feature). -* [#14707](http://dev.ckeditor.com/ticket/14707): Added a new [Copy Formatting](http://ckeditor.com/addon/copyformatting) feature to enable easy copying of styles between your document parts. -* Introduced the completely rewritten [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin: - * Backward incompatibility: The [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) option now defaults to `false`. This option will be deprecated in the future. Use [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) to replicate the effect of setting it to `true`. - * Backward incompatibility: The [`config.pasteFromWordNumberedHeadingToList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordNumberedHeadingToList) and [`config.pasteFromWordRemoveStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveStyles) options were dropped and no longer have any effect on pasted content. - * Major improvements in preservation of list numbering, styling and indentation (nested lists with multiple levels). - * Major improvements in document structure parsing that fix plenty of issues with distorted or missing content after paste. -* Added new translation: Occitan. Thanks to [Cédric Valmary](https://totenoc.eu/)! -* [#10015](http://dev.ckeditor.com/ticket/10015): Keyboard shortcuts (relevant to the operating system in use) will now be displayed in tooltips and context menus. -* [#13794](http://dev.ckeditor.com/ticket/13794): The [Upload Image](http://ckeditor.com/addon/uploadimage) feature now uses `uploaded.width/height` if set. -* [#12541](http://dev.ckeditor.com/ticket/12541): Added the [Upload File](http://ckeditor.com/addon/uploadfile) plugin that lets you upload a file by drag&dropping it into the editor content. -* [#14449](http://dev.ckeditor.com/ticket/14449): Introduced the [Balloon Panel](http://ckeditor.com/addon/balloonpanel) plugin that lets you create stylish floating UI elements for the editor. -* [#12077](https://dev.ckeditor.com/ticket/12077): Added support for the HTML5 `download` attribute in link (``) elements. Selecting the "Force Download" checkbox in the [Link](http://ckeditor.com/addon/link) dialog will cause the linked file to be downloaded automatically. Thanks to [sbusse](https://github.com/sbusse)! -* [#13518](http://dev.ckeditor.com/ticket/13518): Introduced the [`additionalRequestParameters`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition-property-additionalRequestParameters) property for file uploads to make it possible to send additional information about the uploaded file to the server. -* [#14889](http://dev.ckeditor.com/ticket/14889): Added the [`config.image2_altRequired`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_altRequired) option for the [Enhanced Image](http://ckeditor.com/addon/image2) plugin to allow making alternative text a mandatory field. Thanks to [Andrey Fedoseev](https://github.com/andreyfedoseev)! - -Fixed Issues: - -* [#9991](http://dev.ckeditor.com/ticket/9991): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) should only normalize input data. -* [#7209](http://dev.ckeditor.com/ticket/7209): Fixed: Lists with 3 levels not [pasted from Word](http://ckeditor.com/addon/pastefromword) correctly. -* [#14335](http://dev.ckeditor.com/ticket/14335): Fixed: Pasting a numbered list starting with a value different from "1" from Microsoft Word does not work correctly. -* [#14542](http://dev.ckeditor.com/ticket/14542): Fixed: Copying a numbered list from Microsoft Word does not preserve list formatting. -* [#14544](http://dev.ckeditor.com/ticket/14544): Fixed: Copying a nested list from Microsoft Word results in an empty list. -* [#14660](http://dev.ckeditor.com/ticket/14660): Fixed: [Pasting text from Word](http://ckeditor.com/addon/pastefromword) breaks the styling in some cases. -* [#14867](http://dev.ckeditor.com/ticket/14867): [Firefox] Fixed: Text gets stripped when [pasting content from Word](http://ckeditor.com/addon/pastefromword). -* [#2507](http://dev.ckeditor.com/ticket/2507): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) does not detect pasting a part of a paragraph. -* [#3336](http://dev.ckeditor.com/ticket/3336): Fixed: Extra blank row added on top of the content [pasted from Word](http://ckeditor.com/addon/pastefromword). -* [#6115](http://dev.ckeditor.com/ticket/6115): Fixed: When Right-to-Left text direction is applied to a table [pasted from Word](http://ckeditor.com/addon/pastefromword), borders are missing on one side. -* [#6342](http://dev.ckeditor.com/ticket/6342): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filters out a basic text style when it is [configured to use attributes](http://docs.ckeditor.com/#!/guide/dev_basicstyles-section-custom-basic-text-style-definition). -* [#6457](http://dev.ckeditor.com/ticket/6457): [IE] Fixed: [Pasting from Word](http://ckeditor.com/addon/pastefromword) is extremely slow. -* [#6789](http://dev.ckeditor.com/ticket/6789): Fixed: The `mso-list: ignore` style is not handled properly when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#7262](http://dev.ckeditor.com/ticket/7262): Fixed: Lists in preformatted body disappear when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#7662](http://dev.ckeditor.com/ticket/7662): [Opera] Fixed: Extra empty number/bullet shown in the editor body when editing a multi-level list [pasted from Word](http://ckeditor.com/addon/pastefromword). -* [#7807](http://dev.ckeditor.com/ticket/7807): Fixed: Last item in a list not converted to a `
  • ` element after [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#7950](http://dev.ckeditor.com/ticket/7950): [IE] Fixed: Content [from Word pasted](http://ckeditor.com/addon/pastefromword) differently than in other browsers. -* [#7982](http://dev.ckeditor.com/ticket/7982): Fixed: Multi-level lists get split into smaller ones when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#8231](http://dev.ckeditor.com/ticket/8231): [WebKit, Opera] Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts empty paragraphs. -* [#8266](http://dev.ckeditor.com/ticket/8266): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts a blank line at the top. -* [#8341](http://dev.ckeditor.com/ticket/8341), [#7646](http://dev.ckeditor.com/ticket/7646): Fixed: Faulty removal of empty `` elements in [Paste from Word](http://ckeditor.com/addon/pastefromword) content cleanup breaking content formatting. -* [#8754](http://dev.ckeditor.com/ticket/8754): [Firefox] Fixed: Incorrect pasting of multiple nested lists in [Paste from Word](http://ckeditor.com/addon/pastefromword). -* [#8983](http://dev.ckeditor.com/ticket/8983): Fixed: Alignment lost when [pasting from Word](http://ckeditor.com/addon/pastefromword) with [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) set to [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR). -* [#9331](http://dev.ckeditor.com/ticket/9331): [IE] Fixed: [Pasting text from Word](http://ckeditor.com/addon/pastefromword) creates a simple Caesar cipher. -* [#9422](http://dev.ckeditor.com/ticket/9422): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) leaves an unwanted `color:windowtext` style. -* [#10011](http://dev.ckeditor.com/ticket/10011): [IE9-10] Fixed: [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) is ignored under certain conditions. -* [#10643](http://dev.ckeditor.com/ticket/10643): Fixed: Differences between using Ctrl+V and pasting from the [Paste from Word](http://ckeditor.com/addon/pastefromword) dialog. -* [#10784](http://dev.ckeditor.com/ticket/10784): Fixed: Lines missing when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#11294](http://dev.ckeditor.com/ticket/11294): [IE10] Fixed: Font size is not preserved when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#11627](http://dev.ckeditor.com/ticket/11627): Fixed: Missing words when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#12784](http://dev.ckeditor.com/ticket/12784): Fixed: Bulleted list with custom bullets gets changed to a numbered list when [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#13174](http://dev.ckeditor.com/ticket/13174): Fixed: Data loss after [pasting from Word](http://ckeditor.com/addon/pastefromword). -* [#13828](http://dev.ckeditor.com/ticket/13828): Fixed: Widget classes should be added to the wrapper rather than the widget element. -* [#13829](http://dev.ckeditor.com/ticket/13829): Fixed: No class in [Widget](http://ckeditor.com/addon/widget) wrapper to identify the widget type. -* [#13519](http://dev.ckeditor.com/ticket/13519): Server response received when uploading files should be more flexible. - -Other Changes: - -* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type) and [WebSpellChecker](http://ckeditor.com/addon/wsc) plugins: - * Support for the new default Moono-Lisa skin. - * [#121](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/121): Fixed: [Basic Styles](http://ckeditor.com/addon/basicstyles) do not work when SCAYT is enabled. - * [#125](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/125): Fixed: Inline styles are not continued when writing multiple lines of styled text with SCAYT enabled. - * [#127](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/127): Fixed: Uncaught TypeError after enabling SCAYT in the CKEditor `
    ` element. - * [#128](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/128): Fixed: Error thrown after enabling SCAYT caused by conflicts with RequireJS. - -## CKEditor 4.5.11 - -**Security Updates:** - -* [Severity: minor] Fixed the `target="_blank"` vulnerability reported by James Gaskell. - - Issue summary: If a victim had access to a spoofed version of ckeditor.com via HTTP (e.g. due to DNS spoofing, using a hacked public network or mailicious hotspot), then when using a link to the ckeditor.com website it was possible for the attacker to change the current URL of the opening page, even if the opening page was protected with SSL. - - An upgrade is recommended. - -New Features: - -* [#14747](http://dev.ckeditor.com/ticket/14747): The [Enhanced Image](http://ckeditor.com/addon/image2) caption now supports the link `target` attribute. -* [#7154](http://dev.ckeditor.com/ticket/7154): Added support for the "Display Text" field to the [Link](http://ckeditor.com/addon/link) dialog. Thanks to [Ryan Guill](https://github.com/ryanguill)! - -Fixed Issues: - -* [#13362](http://dev.ckeditor.com/ticket/13362): [Blink, WebKit] Fixed: Active widget element is not cached when it is losing focus and it is inside an editable element. -* [#13755](http://dev.ckeditor.com/ticket/13755): [Edge] Fixed: Pasting images does not work. -* [#13548](http://dev.ckeditor.com/ticket/13548): [IE] Fixed: Clicking the [elements path](http://ckeditor.com/addon/elementspath) disables Cut and Copy icons. -* [#13812](http://dev.ckeditor.com/ticket/13812): Fixed: When aborting file upload the placeholder for image is left. -* [#14659](http://dev.ckeditor.com/ticket/14659): [Blink] Fixed: Content scrolled to the top after closing the dialog in a [`
    `-based editor](http://ckeditor.com/addon/divarea). -* [#14825](http://dev.ckeditor.com/ticket/14825): [Edge] Fixed: Focusing the editor causes unwanted scrolling due to dropped support for the `setActive` method. - -## CKEditor 4.5.10 - -Fixed Issues: - -* [#10750](http://dev.ckeditor.com/ticket/10750): Fixed: The editor does not escape the `font-style` family property correctly, removing quotes and whitespace from font names. -* [#14413](http://dev.ckeditor.com/ticket/14413): Fixed: The [Auto Grow](http://ckeditor.com/addon/autogrow) plugin with the [`config.autoGrow_onStartup`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoGrow_onStartup) option set to `true` does not work properly for an editor that is not visible. -* [#14451](http://dev.ckeditor.com/ticket/14451): Fixed: Numeric element ID not escaped properly. Thanks to [Jakub Chalupa](https://github.com/chaluja7)! -* [#14590](http://dev.ckeditor.com/ticket/14590): Fixed: Additional line break appearing after inline elements when switching modes. Thanks to [dpidcock](https://github.com/dpidcock)! -* [#14539](https://dev.ckeditor.com/ticket/14539): Fixed: JAWS reads "selected Blank" instead of "selected " when selecting a widget. -* [#14701](http://dev.ckeditor.com/ticket/14701): Fixed: More precise labels for [Enhanced Image](http://ckeditor.com/addon/image2) and [Placeholder](http://ckeditor.com/addon/placeholder) widgets. -* [#14667](http://dev.ckeditor.com/ticket/14667): [IE] Fixed: Removing background color from selected text removes background color from the whole paragraph. -* [#14252](http://dev.ckeditor.com/ticket/14252): [IE] Fixed: Styles drop-down list does not always reflect the current style of the text line. -* [#14275](http://dev.ckeditor.com/ticket/14275): [IE9+] Fixed: `onerror` and `onload` events are not used in browsers it could have been used when loading scripts dynamically. - -## CKEditor 4.5.9 - -Fixed Issues: - -* [#10685](http://dev.ckeditor.com/ticket/10685): Fixed: Unreadable toolbar icons after updating to the new editor version. Fixed with [6876179](https://github.com/ckeditor/ckeditor-dev/commit/6876179db4ee97e786b07b8fd72e6b4120732185) in [ckeditor-dev](https://github.com/ckeditor/ckeditor-dev) and [6c9189f4](https://github.com/ckeditor/ckeditor-presets/commit/6c9189f46392d2c126854fe8889b820b8c76d291) in [ckeditor-presets](https://github.com/ckeditor/ckeditor-presets). -* [#14573](https://dev.ckeditor.com/ticket/14573): Fixed: Missing [Widget](http://ckeditor.com/addon/widget) drag handler CSS when there are multiple editor instances. -* [#14620](https://dev.ckeditor.com/ticket/14620): Fixed: Setting both the `min-height` style for the `` element and the `height` style for the `` element breaks the [Auto Grow](http://ckeditor.com/addon/autogrow) plugin. -* [#14538](http://dev.ckeditor.com/ticket/14538): Fixed: Keyboard focus goes into an embedded `