Skip to content

Commit 7b2c181

Browse files
Pantheon Automationgreg-1-anderson
Pantheon Automation
authored andcommitted
Update to Drupal 7.92. For more information, see https://www.drupal.org/project/drupal/releases/7.92
1 parent 00fcac4 commit 7b2c181

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+925
-83
lines changed

.htaccess

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44

55
# Protect files and directories from prying eyes.
6-
<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)$">
6+
<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)$">
77
<IfModule mod_authz_core.c>
88
Require all denied
99
</IfModule>

CHANGELOG.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Drupal 7.92, 2022-09-07
2+
-----------------------
3+
- Improved support for PHP 8.1
4+
- Various security hardenings
5+
- Various bug fixes, optimizations and improvements
6+
17
Drupal 7.91, 2022-07-20
28
-----------------------
39
- Fixed security issues:

MAINTAINERS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The branch maintainers for Drupal 7 are:
1313
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
1414
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
1515
- Drew Webber 'mcdruid' https://www.drupal.org/u/mcdruid
16+
- (provisional) Juraj Nemec 'poker10' https://www.drupal.org/u/poker10
1617

1718

1819
Component maintainers

includes/bootstrap.inc

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/**
99
* The current system version.
1010
*/
11-
define('VERSION', '7.91');
11+
define('VERSION', '7.92');
1212

1313
/**
1414
* Core API compatibility.
@@ -2373,7 +2373,7 @@ function drupal_random_bytes($count) {
23732373
// the microtime() - is prepended rather than appended. This is to avoid
23742374
// directly leaking $random_state via the $output stream, which could
23752375
// allow for trivial prediction of further "random" numbers.
2376-
if (strlen($bytes) < $count) {
2376+
if (strlen((string) $bytes) < $count) {
23772377
// Initialize on the first call. The contents of $_SERVER includes a mix of
23782378
// user-specific and system information that varies a little with each page.
23792379
if (!isset($random_state)) {

includes/common.inc

+40-1
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,14 @@ function drupal_http_request($url, array $options = array()) {
11041104
// Redirect to the new location.
11051105
$options['max_redirects']--;
11061106

1107+
// Check if we need to remove any potentially sensitive headers before
1108+
// following the redirect.
1109+
// @see https://www.rfc-editor.org/rfc/rfc9110.html#name-redirection-3xx
1110+
if (_drupal_should_strip_sensitive_headers_on_http_redirect($url, $location)) {
1111+
unset($options['headers']['Cookie']);
1112+
unset($options['headers']['Authorization']);
1113+
}
1114+
11071115
// We need to unset the 'Host' header
11081116
// as we are redirecting to a new location.
11091117
unset($options['headers']['Host']);
@@ -1122,6 +1130,36 @@ function drupal_http_request($url, array $options = array()) {
11221130
return $result;
11231131
}
11241132

1133+
/**
1134+
* Determine whether to strip sensitive headers from a request when redirected.
1135+
*
1136+
* @param string $url
1137+
* The url from the original outbound http request.
1138+
*
1139+
* @param string $location
1140+
* The location to which the request has been redirected.
1141+
*
1142+
* @return boolean
1143+
* Whether sensitive headers should be stripped from the request before
1144+
* following the redirect.
1145+
*/
1146+
function _drupal_should_strip_sensitive_headers_on_http_redirect($url, $location) {
1147+
$url_parsed = parse_url($url);
1148+
$location_parsed = parse_url($location);
1149+
if (!isset($location_parsed['host'])) {
1150+
return FALSE;
1151+
}
1152+
$strip_on_host_change = variable_get('drupal_http_request_strip_sensitive_headers_on_host_change', TRUE);
1153+
$strip_on_https_downgrade = variable_get('drupal_http_request_strip_sensitive_headers_on_https_downgrade', TRUE);
1154+
if ($strip_on_host_change && strcasecmp($url_parsed['host'], $location_parsed['host']) !== 0) {
1155+
return TRUE;
1156+
}
1157+
if ($strip_on_https_downgrade && $url_parsed['scheme'] !== $location_parsed['scheme'] && 'https' !== $location_parsed['scheme']) {
1158+
return TRUE;
1159+
}
1160+
return FALSE;
1161+
}
1162+
11251163
/**
11261164
* Splits an HTTP response status line into components.
11271165
*
@@ -2570,6 +2608,7 @@ function l($text, $path, array $options = array()) {
25702608
$use_theme = FALSE;
25712609
}
25722610
}
2611+
$path = drupal_strip_dangerous_protocols((string) $path);
25732612
if ($use_theme) {
25742613
return theme('link', array('text' => $text, 'path' => $path, 'options' => $options));
25752614
}
@@ -6105,7 +6144,7 @@ function drupal_render_page($page) {
61056144
*/
61066145
function drupal_render(&$elements) {
61076146
// Early-return nothing if user does not have access.
6108-
if (empty($elements) || (isset($elements['#access']) && !$elements['#access'])) {
6147+
if (empty($elements) || !is_array($elements) || (isset($elements['#access']) && !$elements['#access'])) {
61096148
return '';
61106149
}
61116150

includes/database/prefetch.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
286286
case PDO::FETCH_OBJ:
287287
return (object) $this->currentRow;
288288
case PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE:
289-
$class_name = array_unshift($this->currentRow);
289+
$class_name = array_shift($this->currentRow);
290290
// Deliberate no break.
291291
case PDO::FETCH_CLASS:
292292
if (!isset($class_name)) {

includes/database/query.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
19051905
public function __toString() {
19061906
// If the caller forgot to call compile() first, refuse to run.
19071907
if ($this->changed) {
1908-
return NULL;
1908+
return '';
19091909
}
19101910
return $this->stringVersion;
19111911
}

includes/database/select.inc

+34-10
Original file line numberDiff line numberDiff line change
@@ -883,14 +883,18 @@ class SelectQuery extends Query implements SelectQueryInterface {
883883
* 'type' => $join_type (one of INNER, LEFT OUTER, RIGHT OUTER),
884884
* 'table' => $table,
885885
* 'alias' => $alias_of_the_table,
886-
* 'condition' => $condition_clause_on_which_to_join,
886+
* 'condition' => $join_condition (string or Condition object),
887887
* 'arguments' => $array_of_arguments_for_placeholders_in_the condition.
888888
* 'all_fields' => TRUE to SELECT $alias.*, FALSE or NULL otherwise.
889889
* )
890890
*
891891
* If $table is a string, it is taken as the name of a table. If it is
892892
* a SelectQuery object, it is taken as a subquery.
893893
*
894+
* If $join_condition is a Condition object, any arguments should be
895+
* incorporated into the object; a separate array of arguments does not need
896+
* to be provided.
897+
*
894898
* @var array
895899
*/
896900
protected $tables = array();
@@ -1028,6 +1032,10 @@ class SelectQuery extends Query implements SelectQueryInterface {
10281032
if ($table['table'] instanceof SelectQueryInterface) {
10291033
$args += $table['table']->arguments();
10301034
}
1035+
// If the join condition is an object, grab its arguments recursively.
1036+
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
1037+
$args += $table['condition']->arguments();
1038+
}
10311039
}
10321040

10331041
foreach ($this->expressions as $expression) {
@@ -1079,6 +1087,10 @@ class SelectQuery extends Query implements SelectQueryInterface {
10791087
if ($table['table'] instanceof SelectQueryInterface) {
10801088
$table['table']->compile($connection, $queryPlaceholder);
10811089
}
1090+
// Make sure join conditions are also compiled.
1091+
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
1092+
$table['condition']->compile($connection, $queryPlaceholder);
1093+
}
10821094
}
10831095

10841096
// If there are any dependent queries to UNION, compile it recursively.
@@ -1099,6 +1111,11 @@ class SelectQuery extends Query implements SelectQueryInterface {
10991111
return FALSE;
11001112
}
11011113
}
1114+
if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
1115+
if (!$table['condition']->compiled()) {
1116+
return FALSE;
1117+
}
1118+
}
11021119
}
11031120

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

15701587
if (!empty($table['condition'])) {
1571-
$query .= ' ON ' . $table['condition'];
1588+
$query .= ' ON ' . (string) $table['condition'];
15721589
}
15731590
}
15741591

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

1609+
// UNION is a little odd, as the select queries to combine are passed into
1610+
// this query, but syntactically they all end up on the same level.
1611+
if ($this->union) {
1612+
foreach ($this->union as $union) {
1613+
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
1614+
}
1615+
}
1616+
15921617
// ORDER BY
15931618
if ($this->order) {
15941619
$query .= "\nORDER BY ";
@@ -1608,14 +1633,6 @@ class SelectQuery extends Query implements SelectQueryInterface {
16081633
$query .= "\nLIMIT " . (int) $this->range['length'] . " OFFSET " . (int) $this->range['start'];
16091634
}
16101635

1611-
// UNION is a little odd, as the select queries to combine are passed into
1612-
// this query, but syntactically they all end up on the same level.
1613-
if ($this->union) {
1614-
foreach ($this->union as $union) {
1615-
$query .= ' ' . $union['type'] . ' ' . (string) $union['query'];
1616-
}
1617-
}
1618-
16191636
if ($this->forUpdate) {
16201637
$query .= ' FOR UPDATE';
16211638
}
@@ -1624,6 +1641,8 @@ class SelectQuery extends Query implements SelectQueryInterface {
16241641
}
16251642

16261643
public function __clone() {
1644+
parent::__clone();
1645+
16271646
// On cloning, also clone the dependent objects. However, we do not
16281647
// want to clone the database connection object as that would duplicate the
16291648
// connection itself.
@@ -1633,6 +1652,11 @@ class SelectQuery extends Query implements SelectQueryInterface {
16331652
foreach ($this->union as $key => $aggregate) {
16341653
$this->union[$key]['query'] = clone($aggregate['query']);
16351654
}
1655+
foreach ($this->tables as $alias => $table) {
1656+
if ($table['table'] instanceof SelectQueryInterface) {
1657+
$this->tables[$alias]['table'] = clone $table['table'];
1658+
}
1659+
}
16361660
}
16371661
}
16381662

includes/form.inc

+13-2
Original file line numberDiff line numberDiff line change
@@ -4327,10 +4327,14 @@ function theme_form_required_marker($variables) {
43274327
* required. That is especially important for screenreader users to know
43284328
* which field is required.
43294329
*
4330+
* To associate the label with a different field, set the #label_for property
4331+
* to the ID of the desired field.
4332+
*
43304333
* @param $variables
43314334
* An associative array containing:
43324335
* - element: An associative array containing the properties of the element.
4333-
* Properties used: #required, #title, #id, #value, #description.
4336+
* Properties used: #required, #title, #id, #value, #description,
4337+
* #label_for.
43344338
*
43354339
* @ingroup themeable
43364340
*/
@@ -4359,7 +4363,14 @@ function theme_form_element_label($variables) {
43594363
$attributes['class'] = 'element-invisible';
43604364
}
43614365

4362-
if (!empty($element['#id'])) {
4366+
// Use the element's ID as the default value of the "for" attribute (to
4367+
// associate the label with this form element), but allow this to be
4368+
// overridden in order to associate the label with a different form element
4369+
// instead.
4370+
if (!empty($element['#label_for'])) {
4371+
$attributes['for'] = $element['#label_for'];
4372+
}
4373+
elseif (!empty($element['#id'])) {
43634374
$attributes['for'] = $element['#id'];
43644375
}
43654376

includes/locale.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ function locale_add_language($langcode, $name = NULL, $native = NULL, $direction
615615
'direction' => $direction,
616616
'domain' => $domain,
617617
'prefix' => $prefix,
618-
'enabled' => $enabled,
618+
'enabled' => $enabled ? 1 : 0,
619619
))
620620
->execute();
621621

includes/module.inc

+4-3
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,10 @@ function system_list($type) {
142142
foreach ($bootstrap_list as $module) {
143143
drupal_get_filename('module', $module->name, $module->filename);
144144
}
145-
// We only return the module names here since module_list() doesn't need
146-
// the filename itself.
147-
$lists['bootstrap'] = array_keys($bootstrap_list);
145+
// Only return module names here since module_list() doesn't need the
146+
// filename itself. Don't use drupal_map_assoc() as that requires common.inc.
147+
$list = array_keys($bootstrap_list);
148+
$lists['bootstrap'] = (!empty($list) ? array_combine($list, $list) : array());
148149
}
149150
// Otherwise build the list for enabled modules and themes.
150151
elseif (!isset($lists['module_enabled'])) {

includes/pager.inc

+15
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,21 @@ class PagerDefault extends SelectQueryExtender {
164164
}
165165
return $this;
166166
}
167+
168+
/**
169+
* Gets the element ID for this pager query.
170+
*
171+
* The element is used to differentiate different pager queries on the same
172+
* page so that they may be operated independently.
173+
*
174+
* @return
175+
* Element ID that is used to differentiate between different pager
176+
* queries.
177+
*/
178+
public function getElement() {
179+
$this->ensureElement();
180+
return $this->element;
181+
}
167182
}
168183

169184
/**

includes/path.inc

+2
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ function path_load($conditions) {
417417
}
418418
return $select
419419
->fields('url_alias')
420+
->orderBy('pid', 'DESC')
421+
->range(0, 1)
420422
->execute()
421423
->fetchAssoc();
422424
}

includes/stream_wrappers.inc

+6
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,12 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
405405
public function stream_open($uri, $mode, $options, &$opened_path) {
406406
$this->uri = $uri;
407407
$path = $this->getLocalPath();
408+
if ($path === FALSE) {
409+
if ($options & STREAM_REPORT_ERRORS) {
410+
trigger_error('stream_open() filename cannot be empty', E_USER_WARNING);
411+
}
412+
return FALSE;
413+
}
408414
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
409415

410416
if ((bool) $this->handle && $options & STREAM_USE_PATH) {

misc/machine-name.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Drupal.behaviors.machineName = {
2727
attach: function (context, settings) {
2828
var self = this;
2929
$.each(settings.machineName, function (source_id, options) {
30-
var $source = $(source_id, context).addClass('machine-name-source');
30+
var $source = $(source_id, context).addClass('machine-name-source').once('machine-name');
3131
var $target = $(options.target, context).addClass('machine-name-target');
3232
var $suffix = $(options.suffix, context);
3333
var $wrapper = $target.closest('.form-item');

modules/field/modules/list/list.module

+2-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ function _list_values_in_use($field, $values) {
388388
* - 'list_illegal_value': The value is not part of the list of allowed values.
389389
*/
390390
function list_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
391-
$allowed_values = list_allowed_values($field, $instance, $entity_type, $entity);
391+
// Flatten the array before validating to account for optgroups.
392+
$allowed_values = options_array_flatten(list_allowed_values($field, $instance, $entity_type, $entity));
392393
foreach ($items as $delta => $item) {
393394
if (!empty($item['value'])) {
394395
if (!empty($allowed_values) && !isset($allowed_values[$item['value']])) {

modules/field/modules/options/options.test

+5
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,11 @@ class OptionsWidgetsTestCase extends FieldTestCase {
311311
$edit = array("card_1[$langcode]" => '_none');
312312
$this->drupalPost('test-entity/manage/' . $entity->ftid . '/edit', $edit, t('Save'));
313313
$this->assertFieldValues($entity_init, 'card_1', $langcode, array());
314+
315+
// Submit form: select the option from optgroup.
316+
$edit = array("card_1[$langcode]" => 2);
317+
$this->drupalPost(NULL, $edit, t('Save'));
318+
$this->assertFieldValues($entity_init, 'card_1', $langcode, array(2));
314319
}
315320

316321
/**

modules/file/file.field.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function file_field_load($entity_type, $entities, $field, $instances, $langcode,
184184
foreach ($items[$id] as $delta => $item) {
185185
// If the file does not exist, mark the entire item as empty.
186186
if (empty($item['fid']) || !isset($files[$item['fid']])) {
187-
$items[$id][$delta] = NULL;
187+
unset($items[$id][$delta]);
188188
}
189189
else {
190190
$items[$id][$delta] = array_merge((array) $files[$item['fid']], $item);

0 commit comments

Comments
 (0)