Skip to content

Commit

Permalink
Update to Drupal 7.92. For more information, see https://www.drupal.o…
Browse files Browse the repository at this point in the history
  • Loading branch information
Pantheon Automation committed Sep 8, 2022
1 parent 4840710 commit f454508
Show file tree
Hide file tree
Showing 73 changed files with 925 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#

# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Drupal 7.92, 2022-09-07
-----------------------
- Improved support for PHP 8.1
- Various security hardenings
- Various bug fixes, optimizations and improvements

Drupal 7.91, 2022-07-20
-----------------------
- Fixed security issues:
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The branch maintainers for Drupal 7 are:
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- Drew Webber 'mcdruid' https://www.drupal.org/u/mcdruid
- (provisional) Juraj Nemec 'poker10' https://www.drupal.org/u/poker10


Component maintainers
Expand Down
4 changes: 2 additions & 2 deletions includes/bootstrap.inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.91');
define('VERSION', '7.92');

/**
* Core API compatibility.
Expand Down Expand Up @@ -2373,7 +2373,7 @@ function drupal_random_bytes($count) {
// the microtime() - is prepended rather than appended. This is to avoid
// directly leaking $random_state via the $output stream, which could
// allow for trivial prediction of further "random" numbers.
if (strlen($bytes) < $count) {
if (strlen((string) $bytes) < $count) {
// Initialize on the first call. The contents of $_SERVER includes a mix of
// user-specific and system information that varies a little with each page.
if (!isset($random_state)) {
Expand Down
41 changes: 40 additions & 1 deletion includes/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,14 @@ function drupal_http_request($url, array $options = array()) {
// Redirect to the new location.
$options['max_redirects']--;

// Check if we need to remove any potentially sensitive headers before
// following the redirect.
// @see https://www.rfc-editor.org/rfc/rfc9110.html#name-redirection-3xx
if (_drupal_should_strip_sensitive_headers_on_http_redirect($url, $location)) {
unset($options['headers']['Cookie']);
unset($options['headers']['Authorization']);
}

// We need to unset the 'Host' header
// as we are redirecting to a new location.
unset($options['headers']['Host']);
Expand All @@ -1122,6 +1130,36 @@ function drupal_http_request($url, array $options = array()) {
return $result;
}

/**
* Determine whether to strip sensitive headers from a request when redirected.
*
* @param string $url
* The url from the original outbound http request.
*
* @param string $location
* The location to which the request has been redirected.
*
* @return boolean
* Whether sensitive headers should be stripped from the request before
* following the redirect.
*/
function _drupal_should_strip_sensitive_headers_on_http_redirect($url, $location) {
$url_parsed = parse_url($url);
$location_parsed = parse_url($location);
if (!isset($location_parsed['host'])) {
return FALSE;
}
$strip_on_host_change = variable_get('drupal_http_request_strip_sensitive_headers_on_host_change', TRUE);
$strip_on_https_downgrade = variable_get('drupal_http_request_strip_sensitive_headers_on_https_downgrade', TRUE);
if ($strip_on_host_change && strcasecmp($url_parsed['host'], $location_parsed['host']) !== 0) {
return TRUE;
}
if ($strip_on_https_downgrade && $url_parsed['scheme'] !== $location_parsed['scheme'] && 'https' !== $location_parsed['scheme']) {
return TRUE;
}
return FALSE;
}

/**
* Splits an HTTP response status line into components.
*
Expand Down Expand Up @@ -2570,6 +2608,7 @@ function l($text, $path, array $options = array()) {
$use_theme = FALSE;
}
}
$path = drupal_strip_dangerous_protocols((string) $path);
if ($use_theme) {
return theme('link', array('text' => $text, 'path' => $path, 'options' => $options));
}
Expand Down Expand Up @@ -6105,7 +6144,7 @@ function drupal_render_page($page) {
*/
function drupal_render(&$elements) {
// Early-return nothing if user does not have access.
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
if (empty($elements) || !is_array($elements) || (isset($elements['#access']) && !$elements['#access'])) {
return '';
}

Expand Down
2 changes: 1 addition & 1 deletion includes/database/prefetch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
case PDO::FETCH_OBJ:
return (object) $this->currentRow;
case PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE:
$class_name = array_unshift($this->currentRow);
$class_name = array_shift($this->currentRow);
// Deliberate no break.
case PDO::FETCH_CLASS:
if (!isset($class_name)) {
Expand Down
2 changes: 1 addition & 1 deletion includes/database/query.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1905,7 +1905,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
public function __toString() {
// If the caller forgot to call compile() first, refuse to run.
if ($this->changed) {
return NULL;
return '';
}
return $this->stringVersion;
}
Expand Down
44 changes: 34 additions & 10 deletions includes/database/select.inc
Original file line number Diff line number Diff line change
Expand Up @@ -883,14 +883,18 @@ class SelectQuery extends Query implements SelectQueryInterface {
* 'type' => $join_type (one of INNER, LEFT OUTER, RIGHT OUTER),
* 'table' => $table,
* 'alias' => $alias_of_the_table,
* 'condition' => $condition_clause_on_which_to_join,
* 'condition' => $join_condition (string or Condition object),
* 'arguments' => $array_of_arguments_for_placeholders_in_the condition.
* 'all_fields' => TRUE to SELECT $alias.*, FALSE or NULL otherwise.
* )
*
* If $table is a string, it is taken as the name of a table. If it is
* a SelectQuery object, it is taken as a subquery.
*
* If $join_condition is a Condition object, any arguments should be
* incorporated into the object; a separate array of arguments does not need
* to be provided.
*
* @var array
*/
protected $tables = array();
Expand Down Expand Up @@ -1028,6 +1032,10 @@ class SelectQuery extends Query implements SelectQueryInterface {
if ($table['table'] instanceof SelectQueryInterface) {
$args += $table['table']->arguments();
}
// If the join condition is an object, grab its arguments recursively.
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
$args += $table['condition']->arguments();
}
}

foreach ($this->expressions as $expression) {
Expand Down Expand Up @@ -1079,6 +1087,10 @@ class SelectQuery extends Query implements SelectQueryInterface {
if ($table['table'] instanceof SelectQueryInterface) {
$table['table']->compile($connection, $queryPlaceholder);
}
// Make sure join conditions are also compiled.
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
$table['condition']->compile($connection, $queryPlaceholder);
}
}

// If there are any dependent queries to UNION, compile it recursively.
Expand All @@ -1099,6 +1111,11 @@ class SelectQuery extends Query implements SelectQueryInterface {
return FALSE;
}
}
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
if (!$table['condition']->compiled()) {
return FALSE;
}
}
}

foreach ($this->union as $union) {
Expand Down Expand Up @@ -1568,7 +1585,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
$query .= $table_string . ' ' . $this->connection->escapeAlias($table['alias']);

if (!empty($table['condition'])) {
$query .= ' ON ' . $table['condition'];
$query .= ' ON ' . (string) $table['condition'];
}
}

Expand All @@ -1589,6 +1606,14 @@ class SelectQuery extends Query implements SelectQueryInterface {
$query .= "\nHAVING " . $this->having;
}

// UNION is a little odd, as the select queries to combine are passed into
// this query, but syntactically they all end up on the same level.
if ($this->union) {
foreach ($this->union as $union) {
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
}
}

// ORDER BY
if ($this->order) {
$query .= "\nORDER BY ";
Expand All @@ -1608,14 +1633,6 @@ class SelectQuery extends Query implements SelectQueryInterface {
$query .= "\nLIMIT " . (int) $this->range['length'] . " OFFSET " . (int) $this->range['start'];
}

// UNION is a little odd, as the select queries to combine are passed into
// this query, but syntactically they all end up on the same level.
if ($this->union) {
foreach ($this->union as $union) {
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
}
}

if ($this->forUpdate) {
$query .= ' FOR UPDATE';
}
Expand All @@ -1624,6 +1641,8 @@ class SelectQuery extends Query implements SelectQueryInterface {
}

public function __clone() {
parent::__clone();

// On cloning, also clone the dependent objects. However, we do not
// want to clone the database connection object as that would duplicate the
// connection itself.
Expand All @@ -1633,6 +1652,11 @@ class SelectQuery extends Query implements SelectQueryInterface {
foreach ($this->union as $key => $aggregate) {
$this->union[$key]['query'] = clone($aggregate['query']);
}
foreach ($this->tables as $alias => $table) {
if ($table['table'] instanceof SelectQueryInterface) {
$this->tables[$alias]['table'] = clone $table['table'];
}
}
}
}

Expand Down
15 changes: 13 additions & 2 deletions includes/form.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4327,10 +4327,14 @@ function theme_form_required_marker($variables) {
* required. That is especially important for screenreader users to know
* which field is required.
*
* To associate the label with a different field, set the #label_for property
* to the ID of the desired field.
*
* @param $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Properties used: #required, #title, #id, #value, #description.
* Properties used: #required, #title, #id, #value, #description,
* #label_for.
*
* @ingroup themeable
*/
Expand Down Expand Up @@ -4359,7 +4363,14 @@ function theme_form_element_label($variables) {
$attributes['class'] = 'element-invisible';
}

if (!empty($element['#id'])) {
// Use the element's ID as the default value of the "for" attribute (to
// associate the label with this form element), but allow this to be
// overridden in order to associate the label with a different form element
// instead.
if (!empty($element['#label_for'])) {
$attributes['for'] = $element['#label_for'];
}
elseif (!empty($element['#id'])) {
$attributes['for'] = $element['#id'];
}

Expand Down
2 changes: 1 addition & 1 deletion includes/locale.inc
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ function locale_add_language($langcode, $name = NULL, $native = NULL, $direction
'direction' => $direction,
'domain' => $domain,
'prefix' => $prefix,
'enabled' => $enabled,
'enabled' => $enabled ? 1 : 0,
))
->execute();

Expand Down
7 changes: 4 additions & 3 deletions includes/module.inc
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,10 @@ function system_list($type) {
foreach ($bootstrap_list as $module) {
drupal_get_filename('module', $module->name, $module->filename);
}
// We only return the module names here since module_list() doesn't need
// the filename itself.
$lists['bootstrap'] = array_keys($bootstrap_list);
// Only return module names here since module_list() doesn't need the
// filename itself. Don't use drupal_map_assoc() as that requires common.inc.
$list = array_keys($bootstrap_list);
$lists['bootstrap'] = (!empty($list) ? array_combine($list, $list) : array());
}
// Otherwise build the list for enabled modules and themes.
elseif (!isset($lists['module_enabled'])) {
Expand Down
15 changes: 15 additions & 0 deletions includes/pager.inc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,21 @@ class PagerDefault extends SelectQueryExtender {
}
return $this;
}

/**
* Gets the element ID for this pager query.
*
* The element is used to differentiate different pager queries on the same
* page so that they may be operated independently.
*
* @return
* Element ID that is used to differentiate between different pager
* queries.
*/
public function getElement() {
$this->ensureElement();
return $this->element;
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions includes/path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ function path_load($conditions) {
}
return $select
->fields('url_alias')
->orderBy('pid', 'DESC')
->range(0, 1)
->execute()
->fetchAssoc();
}
Expand Down
6 changes: 6 additions & 0 deletions includes/stream_wrappers.inc
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,12 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
public function stream_open($uri, $mode, $options, &$opened_path) {
$this->uri = $uri;
$path = $this->getLocalPath();
if ($path === FALSE) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error('stream_open() filename cannot be empty', E_USER_WARNING);
}
return FALSE;
}
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);

if ((bool) $this->handle && $options & STREAM_USE_PATH) {
Expand Down
2 changes: 1 addition & 1 deletion misc/machine-name.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Drupal.behaviors.machineName = {
attach: function (context, settings) {
var self = this;
$.each(settings.machineName, function (source_id, options) {
var $source = $(source_id, context).addClass('machine-name-source');
var $source = $(source_id, context).addClass('machine-name-source').once('machine-name');
var $target = $(options.target, context).addClass('machine-name-target');
var $suffix = $(options.suffix, context);
var $wrapper = $target.closest('.form-item');
Expand Down
3 changes: 2 additions & 1 deletion modules/field/modules/list/list.module
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ function _list_values_in_use($field, $values) {
* - 'list_illegal_value': The value is not part of the list of allowed values.
*/
function list_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
$allowed_values = list_allowed_values($field, $instance, $entity_type, $entity);
// Flatten the array before validating to account for optgroups.
$allowed_values = options_array_flatten(list_allowed_values($field, $instance, $entity_type, $entity));
foreach ($items as $delta => $item) {
if (!empty($item['value'])) {
if (!empty($allowed_values) && !isset($allowed_values[$item['value']])) {
Expand Down
5 changes: 5 additions & 0 deletions modules/field/modules/options/options.test
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@ class OptionsWidgetsTestCase extends FieldTestCase {
$edit = array("card_1[$langcode]" => '_none');
$this->drupalPost('test-entity/manage/' . $entity->ftid . '/edit', $edit, t('Save'));
$this->assertFieldValues($entity_init, 'card_1', $langcode, array());

// Submit form: select the option from optgroup.
$edit = array("card_1[$langcode]" => 2);
$this->drupalPost(NULL, $edit, t('Save'));
$this->assertFieldValues($entity_init, 'card_1', $langcode, array(2));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion modules/file/file.field.inc
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function file_field_load($entity_type, $entities, $field, $instances, $langcode,
foreach ($items[$id] as $delta => $item) {
// If the file does not exist, mark the entire item as empty.
if (empty($item['fid']) || !isset($files[$item['fid']])) {
$items[$id][$delta] = NULL;
unset($items[$id][$delta]);
}
else {
$items[$id][$delta] = array_merge((array) $files[$item['fid']], $item);
Expand Down
Loading

0 comments on commit f454508

Please sign in to comment.