Skip to content

Commit c989758

Browse files
1619039763: Proposed release for 7.x-1.18.16 (#116)
1 parent 6d8a779 commit c989758

File tree

84 files changed

+1044
-276
lines changed

Some content is hidden

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

84 files changed

+1044
-276
lines changed

CHANGELOG.txt

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
Drupal 7.80, 2021-04-20
2+
-----------------------
3+
- Fixed security issues:
4+
- SA-CORE-2021-002
5+
6+
Drupal 7.79, 2021-04-07
7+
-----------------------
8+
- Initial support for PHP 8
9+
- Support for SameSite cookie attribute
10+
- Avoid write for unchanged fields (opt-in)
11+
112
Drupal 7.78, 2021-01-19
213
-----------------------
314
- Fixed security issues:

includes/bootstrap.inc

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

1313
/**
1414
* Core API compatibility.
@@ -2621,13 +2621,10 @@ function drupal_get_hash_salt() {
26212621
* The filename that the error was raised in.
26222622
* @param $line
26232623
* The line number the error was raised at.
2624-
* @param $context
2625-
* An array that points to the active symbol table at the point the error
2626-
* occurred.
26272624
*/
2628-
function _drupal_error_handler($error_level, $message, $filename, $line, $context) {
2625+
function _drupal_error_handler($error_level, $message, $filename, $line) {
26292626
require_once DRUPAL_ROOT . '/includes/errors.inc';
2630-
_drupal_error_handler_real($error_level, $message, $filename, $line, $context);
2627+
_drupal_error_handler_real($error_level, $message, $filename, $line);
26312628
}
26322629

26332630
/**
@@ -3920,3 +3917,85 @@ function drupal_clear_opcode_cache($filepath) {
39203917
@apc_delete_file($filepath);
39213918
}
39223919
}
3920+
3921+
/**
3922+
* Drupal's wrapper around PHP's setcookie() function.
3923+
*
3924+
* This allows the cookie's $value and $options to be altered.
3925+
*
3926+
* @param $name
3927+
* The name of the cookie.
3928+
* @param $value
3929+
* The value of the cookie.
3930+
* @param $options
3931+
* An associative array which may have any of the keys expires, path, domain,
3932+
* secure, httponly, samesite.
3933+
*
3934+
* @see setcookie()
3935+
* @ingroup php_wrappers
3936+
*/
3937+
function drupal_setcookie($name, $value, $options) {
3938+
$options = _drupal_cookie_params($options);
3939+
if (\PHP_VERSION_ID >= 70300) {
3940+
setcookie($name, $value, $options);
3941+
}
3942+
else {
3943+
setcookie($name, $value, $options['expires'], $options['path'], $options['domain'], $options['secure'], $options['httponly']);
3944+
}
3945+
}
3946+
3947+
/**
3948+
* Process the params for cookies. This emulates support for the SameSite
3949+
* attribute in earlier versions of PHP, and allows the value of that attribute
3950+
* to be overridden.
3951+
*
3952+
* @param $options
3953+
* An associative array which may have any of the keys expires, path, domain,
3954+
* secure, httponly, samesite.
3955+
*
3956+
* @return
3957+
* An associative array which may have any of the keys expires, path, domain,
3958+
* secure, httponly, and samesite.
3959+
*/
3960+
function _drupal_cookie_params($options) {
3961+
$options['samesite'] = _drupal_samesite_cookie($options);
3962+
if (\PHP_VERSION_ID < 70300) {
3963+
// Emulate SameSite support in older PHP versions.
3964+
if (!empty($options['samesite'])) {
3965+
// Ensure the SameSite attribute is only added once.
3966+
if (!preg_match('/SameSite=/i', $options['path'])) {
3967+
$options['path'] .= '; SameSite=' . $options['samesite'];
3968+
}
3969+
}
3970+
}
3971+
return $options;
3972+
}
3973+
3974+
/**
3975+
* Determine the value for the samesite cookie attribute, in the following order
3976+
* of precedence:
3977+
*
3978+
* 1) A value explicitly passed to drupal_setcookie()
3979+
* 2) A value set in $conf['samesite_cookie_value']
3980+
* 3) The setting from php ini
3981+
* 4) The default of None, or FALSE (no attribute) if the cookie is not Secure
3982+
*
3983+
* @param $options
3984+
* An associative array as passed to drupal_setcookie().
3985+
* @return
3986+
* The value for the samesite cookie attribute.
3987+
*/
3988+
function _drupal_samesite_cookie($options) {
3989+
if (isset($options['samesite'])) {
3990+
return $options['samesite'];
3991+
}
3992+
$override = variable_get('samesite_cookie_value', NULL);
3993+
if ($override !== NULL) {
3994+
return $override;
3995+
}
3996+
$ini_options = session_get_cookie_params();
3997+
if (isset($ini_options['samesite'])) {
3998+
return $ini_options['samesite'];
3999+
}
4000+
return empty($options['secure']) ? FALSE : 'None';
4001+
}

includes/common.inc

+12-3
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@ function _filter_xss_split($m, $store = FALSE) {
15591559
return '&lt;';
15601560
}
15611561

1562-
if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9\-]+)([^>]*)>?|(<!--.*?-->)$%', $string, $matches)) {
1562+
if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9\-]+)\s*([^>]*)>?|(<!--.*?-->)$%', $string, $matches)) {
15631563
// Seriously malformed.
15641564
return '';
15651565
}
@@ -1618,7 +1618,13 @@ function _filter_xss_attributes($attr) {
16181618
// Attribute name, href for instance.
16191619
if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) {
16201620
$attrname = strtolower($match[1]);
1621-
$skip = ($attrname == 'style' || substr($attrname, 0, 2) == 'on');
1621+
$skip = (
1622+
$attrname == 'style' ||
1623+
substr($attrname, 0, 2) == 'on' ||
1624+
substr($attrname, 0, 1) == '-' ||
1625+
// Ignore long attributes to avoid unnecessary processing overhead.
1626+
strlen($attrname) > 96
1627+
);
16221628
$working = $mode = 1;
16231629
$attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
16241630
}
@@ -2329,6 +2335,7 @@ function url($path = NULL, array $options = array()) {
23292335
}
23302336
elseif (!empty($path) && !$options['alias']) {
23312337
$language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : '';
2338+
require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'includes/path.inc');
23322339
$alias = drupal_get_path_alias($original_path, $language);
23332340
if ($alias != $original_path) {
23342341
// Strip leading slashes from internal path aliases to prevent them
@@ -5182,7 +5189,9 @@ function drupal_build_js_cache($files) {
51825189

51835190
// Allow modules to act on the js_cache before writing to disk.
51845191
drupal_alter('js_cache', $contents);
5185-
5192+
5193+
// Remove JS source and source mapping urls or these may cause 404 errors.
5194+
$contents = preg_replace('/\/\/(#|@)\s(sourceURL|sourceMappingURL)=\s*(\S*?)\s*$/m', '', $contents);
51865195
// Prefix filename to prevent blocking by firewalls which reject files
51875196
// starting with "ad*".
51885197
$filename = 'js_' . drupal_hash_base64($contents) . '.js';

includes/database/database.inc

+36-12
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
*
185185
* @see http://php.net/manual/book.pdo.php
186186
*/
187-
abstract class DatabaseConnection extends PDO {
187+
abstract class DatabaseConnection {
188188

189189
/**
190190
* The database target this connection is for.
@@ -261,6 +261,13 @@ abstract class DatabaseConnection extends PDO {
261261
*/
262262
protected $temporaryNameIndex = 0;
263263

264+
/**
265+
* The actual PDO connection.
266+
*
267+
* @var \PDO
268+
*/
269+
protected $connection;
270+
264271
/**
265272
* The connection information for this connection object.
266273
*
@@ -325,14 +332,27 @@ abstract class DatabaseConnection extends PDO {
325332
$driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
326333

327334
// Call PDO::__construct and PDO::setAttribute.
328-
parent::__construct($dsn, $username, $password, $driver_options);
335+
$this->connection = new PDO($dsn, $username, $password, $driver_options);
329336

330337
// Set a Statement class, unless the driver opted out.
331338
if (!empty($this->statementClass)) {
332-
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
339+
$this->connection->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
333340
}
334341
}
335342

343+
/**
344+
* Proxy possible direct calls to the \PDO methods.
345+
*
346+
* Since PHP8.0 the signature of the the \PDO::query() method has changed,
347+
* and this class can't extending \PDO any more.
348+
*
349+
* However, for the BC, proxy any calls to the \PDO methods to the actual
350+
* PDO connection object.
351+
*/
352+
public function __call($name, $arguments) {
353+
return call_user_func_array(array($this->connection, $name), $arguments);
354+
}
355+
336356
/**
337357
* Destroys this Connection object.
338358
*
@@ -346,7 +366,7 @@ abstract class DatabaseConnection extends PDO {
346366
// The Statement class attribute only accepts a new value that presents a
347367
// proper callable, so we reset it to PDOStatement.
348368
if (!empty($this->statementClass)) {
349-
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array()));
369+
$this->connection->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array()));
350370
}
351371
$this->schema = NULL;
352372
}
@@ -521,7 +541,7 @@ abstract class DatabaseConnection extends PDO {
521541
$query = $this->prefixTables($query);
522542

523543
// Call PDO::prepare.
524-
return parent::prepare($query);
544+
return $this->connection->prepare($query);
525545
}
526546

527547
/**
@@ -733,7 +753,7 @@ abstract class DatabaseConnection extends PDO {
733753
case Database::RETURN_AFFECTED:
734754
return $stmt->rowCount();
735755
case Database::RETURN_INSERT_ID:
736-
return $this->lastInsertId();
756+
return $this->connection->lastInsertId();
737757
case Database::RETURN_NULL:
738758
return;
739759
default:
@@ -1116,7 +1136,7 @@ abstract class DatabaseConnection extends PDO {
11161136
$rolled_back_other_active_savepoints = TRUE;
11171137
}
11181138
}
1119-
parent::rollBack();
1139+
$this->connection->rollBack();
11201140
if ($rolled_back_other_active_savepoints) {
11211141
throw new DatabaseTransactionOutOfOrderException();
11221142
}
@@ -1144,7 +1164,7 @@ abstract class DatabaseConnection extends PDO {
11441164
$this->query('SAVEPOINT ' . $name);
11451165
}
11461166
else {
1147-
parent::beginTransaction();
1167+
$this->connection->beginTransaction();
11481168
}
11491169
$this->transactionLayers[$name] = $name;
11501170
}
@@ -1195,7 +1215,7 @@ abstract class DatabaseConnection extends PDO {
11951215
// If there are no more layers left then we should commit.
11961216
unset($this->transactionLayers[$name]);
11971217
if (empty($this->transactionLayers)) {
1198-
if (!parent::commit()) {
1218+
if (!$this->connection->commit()) {
11991219
throw new DatabaseTransactionCommitFailedException();
12001220
}
12011221
}
@@ -1279,7 +1299,7 @@ abstract class DatabaseConnection extends PDO {
12791299
* Returns the version of the database server.
12801300
*/
12811301
public function version() {
1282-
return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
1302+
return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
12831303
}
12841304

12851305
/**
@@ -1724,12 +1744,16 @@ abstract class Database {
17241744
*
17251745
* @param $key
17261746
* The connection key.
1747+
* @param $close
1748+
* Whether to close the connection.
17271749
* @return
17281750
* TRUE in case of success, FALSE otherwise.
17291751
*/
1730-
final public static function removeConnection($key) {
1752+
final public static function removeConnection($key, $close = TRUE) {
17311753
if (isset(self::$databaseInfo[$key])) {
1732-
self::closeConnection(NULL, $key);
1754+
if ($close) {
1755+
self::closeConnection(NULL, $key);
1756+
}
17331757
unset(self::$databaseInfo[$key]);
17341758
return TRUE;
17351759
}

0 commit comments

Comments
 (0)