Drupal: update code 7.80

This commit is contained in:
Robert 2021-05-24 15:37:55 +02:00
parent e9708f5d4d
commit 51392c687d
208 changed files with 11474 additions and 614 deletions

View File

@ -1,3 +1,14 @@
Drupal 7.80, 2021-04-20
-----------------------
- Fixed security issues:
- SA-CORE-2021-002
Drupal 7.79, 2021-04-07
-----------------------
- Initial support for PHP 8
- Support for SameSite cookie attribute
- Avoid write for unchanged fields (opt-in)
Drupal 7.78, 2021-01-19 Drupal 7.78, 2021-01-19
----------------------- -----------------------
- Fixed security issues: - Fixed security issues:

View File

@ -8,7 +8,7 @@
/** /**
* The current system version. * The current system version.
*/ */
define('VERSION', '7.78'); define('VERSION', '7.80');
/** /**
* Core API compatibility. * Core API compatibility.
@ -2596,13 +2596,10 @@ function drupal_get_hash_salt() {
* The filename that the error was raised in. * The filename that the error was raised in.
* @param $line * @param $line
* The line number the error was raised at. * The line number the error was raised at.
* @param $context
* An array that points to the active symbol table at the point the error
* occurred.
*/ */
function _drupal_error_handler($error_level, $message, $filename, $line, $context) { function _drupal_error_handler($error_level, $message, $filename, $line) {
require_once DRUPAL_ROOT . '/includes/errors.inc'; require_once DRUPAL_ROOT . '/includes/errors.inc';
_drupal_error_handler_real($error_level, $message, $filename, $line, $context); _drupal_error_handler_real($error_level, $message, $filename, $line);
} }
/** /**
@ -3879,3 +3876,85 @@ function drupal_clear_opcode_cache($filepath) {
@apc_delete_file($filepath); @apc_delete_file($filepath);
} }
} }
/**
* Drupal's wrapper around PHP's setcookie() function.
*
* This allows the cookie's $value and $options to be altered.
*
* @param $name
* The name of the cookie.
* @param $value
* The value of the cookie.
* @param $options
* An associative array which may have any of the keys expires, path, domain,
* secure, httponly, samesite.
*
* @see setcookie()
* @ingroup php_wrappers
*/
function drupal_setcookie($name, $value, $options) {
$options = _drupal_cookie_params($options);
if (\PHP_VERSION_ID >= 70300) {
setcookie($name, $value, $options);
}
else {
setcookie($name, $value, $options['expires'], $options['path'], $options['domain'], $options['secure'], $options['httponly']);
}
}
/**
* Process the params for cookies. This emulates support for the SameSite
* attribute in earlier versions of PHP, and allows the value of that attribute
* to be overridden.
*
* @param $options
* An associative array which may have any of the keys expires, path, domain,
* secure, httponly, samesite.
*
* @return
* An associative array which may have any of the keys expires, path, domain,
* secure, httponly, and samesite.
*/
function _drupal_cookie_params($options) {
$options['samesite'] = _drupal_samesite_cookie($options);
if (\PHP_VERSION_ID < 70300) {
// Emulate SameSite support in older PHP versions.
if (!empty($options['samesite'])) {
// Ensure the SameSite attribute is only added once.
if (!preg_match('/SameSite=/i', $options['path'])) {
$options['path'] .= '; SameSite=' . $options['samesite'];
}
}
}
return $options;
}
/**
* Determine the value for the samesite cookie attribute, in the following order
* of precedence:
*
* 1) A value explicitly passed to drupal_setcookie()
* 2) A value set in $conf['samesite_cookie_value']
* 3) The setting from php ini
* 4) The default of None, or FALSE (no attribute) if the cookie is not Secure
*
* @param $options
* An associative array as passed to drupal_setcookie().
* @return
* The value for the samesite cookie attribute.
*/
function _drupal_samesite_cookie($options) {
if (isset($options['samesite'])) {
return $options['samesite'];
}
$override = variable_get('samesite_cookie_value', NULL);
if ($override !== NULL) {
return $override;
}
$ini_options = session_get_cookie_params();
if (isset($ini_options['samesite'])) {
return $ini_options['samesite'];
}
return empty($options['secure']) ? FALSE : 'None';
}

View File

@ -1559,7 +1559,7 @@ function _filter_xss_split($m, $store = FALSE) {
return '&lt;'; return '&lt;';
} }
if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9\-]+)([^>]*)>?|(<!--.*?-->)$%', $string, $matches)) { if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9\-]+)\s*([^>]*)>?|(<!--.*?-->)$%', $string, $matches)) {
// Seriously malformed. // Seriously malformed.
return ''; return '';
} }
@ -1618,7 +1618,13 @@ function _filter_xss_attributes($attr) {
// Attribute name, href for instance. // Attribute name, href for instance.
if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) { if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) {
$attrname = strtolower($match[1]); $attrname = strtolower($match[1]);
$skip = ($attrname == 'style' || substr($attrname, 0, 2) == 'on'); $skip = (
$attrname == 'style' ||
substr($attrname, 0, 2) == 'on' ||
substr($attrname, 0, 1) == '-' ||
// Ignore long attributes to avoid unnecessary processing overhead.
strlen($attrname) > 96
);
$working = $mode = 1; $working = $mode = 1;
$attr = preg_replace('/^[-a-zA-Z]+/', '', $attr); $attr = preg_replace('/^[-a-zA-Z]+/', '', $attr);
} }
@ -2329,6 +2335,7 @@ function url($path = NULL, array $options = array()) {
} }
elseif (!empty($path) && !$options['alias']) { elseif (!empty($path) && !$options['alias']) {
$language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : ''; $language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : '';
require_once DRUPAL_ROOT . '/' . variable_get('path_inc', 'includes/path.inc');
$alias = drupal_get_path_alias($original_path, $language); $alias = drupal_get_path_alias($original_path, $language);
if ($alias != $original_path) { if ($alias != $original_path) {
// Strip leading slashes from internal path aliases to prevent them // Strip leading slashes from internal path aliases to prevent them
@ -5166,6 +5173,8 @@ function drupal_build_js_cache($files) {
$contents .= file_get_contents($path) . ";\n"; $contents .= file_get_contents($path) . ";\n";
} }
} }
// Remove JS source and source mapping urls or these may cause 404 errors.
$contents = preg_replace('/\/\/(#|@)\s(sourceURL|sourceMappingURL)=\s*(\S*?)\s*$/m', '', $contents);
// Prefix filename to prevent blocking by firewalls which reject files // Prefix filename to prevent blocking by firewalls which reject files
// starting with "ad*". // starting with "ad*".
$filename = 'js_' . drupal_hash_base64($contents) . '.js'; $filename = 'js_' . drupal_hash_base64($contents) . '.js';

View File

@ -184,7 +184,7 @@
* *
* @see http://php.net/manual/book.pdo.php * @see http://php.net/manual/book.pdo.php
*/ */
abstract class DatabaseConnection extends PDO { abstract class DatabaseConnection {
/** /**
* The database target this connection is for. * The database target this connection is for.
@ -261,6 +261,13 @@ abstract class DatabaseConnection extends PDO {
*/ */
protected $temporaryNameIndex = 0; protected $temporaryNameIndex = 0;
/**
* The actual PDO connection.
*
* @var \PDO
*/
protected $connection;
/** /**
* The connection information for this connection object. * The connection information for this connection object.
* *
@ -325,14 +332,27 @@ abstract class DatabaseConnection extends PDO {
$driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
// Call PDO::__construct and PDO::setAttribute. // Call PDO::__construct and PDO::setAttribute.
parent::__construct($dsn, $username, $password, $driver_options); $this->connection = new PDO($dsn, $username, $password, $driver_options);
// Set a Statement class, unless the driver opted out. // Set a Statement class, unless the driver opted out.
if (!empty($this->statementClass)) { if (!empty($this->statementClass)) {
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this))); $this->connection->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this)));
} }
} }
/**
* Proxy possible direct calls to the \PDO methods.
*
* Since PHP8.0 the signature of the the \PDO::query() method has changed,
* and this class can't extending \PDO any more.
*
* However, for the BC, proxy any calls to the \PDO methods to the actual
* PDO connection object.
*/
public function __call($name, $arguments) {
return call_user_func_array(array($this->connection, $name), $arguments);
}
/** /**
* Destroys this Connection object. * Destroys this Connection object.
* *
@ -346,7 +366,7 @@ abstract class DatabaseConnection extends PDO {
// The Statement class attribute only accepts a new value that presents a // The Statement class attribute only accepts a new value that presents a
// proper callable, so we reset it to PDOStatement. // proper callable, so we reset it to PDOStatement.
if (!empty($this->statementClass)) { if (!empty($this->statementClass)) {
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array())); $this->connection->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array()));
} }
$this->schema = NULL; $this->schema = NULL;
} }
@ -521,7 +541,7 @@ abstract class DatabaseConnection extends PDO {
$query = $this->prefixTables($query); $query = $this->prefixTables($query);
// Call PDO::prepare. // Call PDO::prepare.
return parent::prepare($query); return $this->connection->prepare($query);
} }
/** /**
@ -733,7 +753,7 @@ abstract class DatabaseConnection extends PDO {
case Database::RETURN_AFFECTED: case Database::RETURN_AFFECTED:
return $stmt->rowCount(); return $stmt->rowCount();
case Database::RETURN_INSERT_ID: case Database::RETURN_INSERT_ID:
return $this->lastInsertId(); return $this->connection->lastInsertId();
case Database::RETURN_NULL: case Database::RETURN_NULL:
return; return;
default: default:
@ -1116,7 +1136,7 @@ abstract class DatabaseConnection extends PDO {
$rolled_back_other_active_savepoints = TRUE; $rolled_back_other_active_savepoints = TRUE;
} }
} }
parent::rollBack(); $this->connection->rollBack();
if ($rolled_back_other_active_savepoints) { if ($rolled_back_other_active_savepoints) {
throw new DatabaseTransactionOutOfOrderException(); throw new DatabaseTransactionOutOfOrderException();
} }
@ -1144,7 +1164,7 @@ abstract class DatabaseConnection extends PDO {
$this->query('SAVEPOINT ' . $name); $this->query('SAVEPOINT ' . $name);
} }
else { else {
parent::beginTransaction(); $this->connection->beginTransaction();
} }
$this->transactionLayers[$name] = $name; $this->transactionLayers[$name] = $name;
} }
@ -1195,7 +1215,7 @@ abstract class DatabaseConnection extends PDO {
// If there are no more layers left then we should commit. // If there are no more layers left then we should commit.
unset($this->transactionLayers[$name]); unset($this->transactionLayers[$name]);
if (empty($this->transactionLayers)) { if (empty($this->transactionLayers)) {
if (!parent::commit()) { if (!$this->connection->commit()) {
throw new DatabaseTransactionCommitFailedException(); throw new DatabaseTransactionCommitFailedException();
} }
} }
@ -1279,7 +1299,7 @@ abstract class DatabaseConnection extends PDO {
* Returns the version of the database server. * Returns the version of the database server.
*/ */
public function version() { public function version() {
return $this->getAttribute(PDO::ATTR_SERVER_VERSION); return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
} }
/** /**
@ -1724,12 +1744,16 @@ abstract class Database {
* *
* @param $key * @param $key
* The connection key. * The connection key.
* @param $close
* Whether to close the connection.
* @return * @return
* TRUE in case of success, FALSE otherwise. * TRUE in case of success, FALSE otherwise.
*/ */
final public static function removeConnection($key) { final public static function removeConnection($key, $close = TRUE) {
if (isset(self::$databaseInfo[$key])) { if (isset(self::$databaseInfo[$key])) {
self::closeConnection(NULL, $key); if ($close) {
self::closeConnection(NULL, $key);
}
unset(self::$databaseInfo[$key]); unset(self::$databaseInfo[$key]);
return TRUE; return TRUE;
} }

View File

@ -345,10 +345,10 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci' // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8. // for UTF-8.
if (!empty($connection_options['collation'])) { if (!empty($connection_options['collation'])) {
$this->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']); $this->connection->exec('SET NAMES ' . $charset . ' COLLATE ' . $connection_options['collation']);
} }
else { else {
$this->exec('SET NAMES ' . $charset); $this->connection->exec('SET NAMES ' . $charset);
} }
// Set MySQL init_commands if not already defined. Default Drupal's MySQL // Set MySQL init_commands if not already defined. Default Drupal's MySQL
@ -366,7 +366,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
$sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO'; $sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO';
// NO_AUTO_CREATE_USER was removed in MySQL 8.0.11 // NO_AUTO_CREATE_USER was removed in MySQL 8.0.11
// https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-deprecation-removal // https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-deprecation-removal
if (version_compare($this->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11', '<')) { if (version_compare($this->connection->getAttribute(PDO::ATTR_SERVER_VERSION), '8.0.11', '<')) {
$sql_mode .= ',NO_AUTO_CREATE_USER'; $sql_mode .= ',NO_AUTO_CREATE_USER';
} }
$connection_options['init_commands'] += array( $connection_options['init_commands'] += array(
@ -375,7 +375,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// Execute initial commands. // Execute initial commands.
foreach ($connection_options['init_commands'] as $sql) { foreach ($connection_options['init_commands'] as $sql) {
$this->exec($sql); $this->connection->exec($sql);
} }
} }
@ -536,7 +536,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
// If there are no more layers left then we should commit. // If there are no more layers left then we should commit.
unset($this->transactionLayers[$name]); unset($this->transactionLayers[$name]);
if (empty($this->transactionLayers)) { if (empty($this->transactionLayers)) {
if (!PDO::commit()) { if (!$this->doCommit()) {
throw new DatabaseTransactionCommitFailedException(); throw new DatabaseTransactionCommitFailedException();
} }
} }
@ -559,7 +559,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
$this->transactionLayers = array(); $this->transactionLayers = array();
// We also have to explain to PDO that the transaction stack has // We also have to explain to PDO that the transaction stack has
// been cleaned-up. // been cleaned-up.
PDO::commit(); $this->doCommit();
} }
else { else {
throw $e; throw $e;
@ -569,6 +569,53 @@ class DatabaseConnection_mysql extends DatabaseConnection {
} }
} }
/**
* Do the actual commit, including a workaround for PHP 8 behaviour changes.
*
* @return bool
* Success or otherwise of the commit.
*/
protected function doCommit() {
if ($this->connection->inTransaction()) {
return $this->connection->commit();
}
else {
// In PHP 8.0 a PDOException is thrown when a commit is attempted with no
// transaction active. In previous PHP versions this failed silently.
return TRUE;
}
}
/**
* {@inheritdoc}
*/
public function rollback($savepoint_name = 'drupal_transaction') {
// MySQL will automatically commit transactions when tables are altered or
// created (DDL transactions are not supported). Prevent triggering an
// exception to ensure that the error that has caused the rollback is
// properly reported.
if (!$this->connection->inTransaction()) {
// Before PHP 8 $this->connection->inTransaction() will return TRUE and
// $this->connection->rollback() does not throw an exception; the
// following code is unreachable.
// If \DatabaseConnection::rollback() would throw an
// exception then continue to throw an exception.
if (!$this->inTransaction()) {
throw new DatabaseTransactionNoActiveException();
}
// A previous rollback to an earlier savepoint may mean that the savepoint
// in question has already been accidentally committed.
if (!isset($this->transactionLayers[$savepoint_name])) {
throw new DatabaseTransactionNoActiveException();
}
trigger_error('Rollback attempted when there is no active transaction. This can cause data integrity issues.', E_USER_WARNING);
return;
}
return parent::rollback($savepoint_name);
}
public function utf8mb4IsConfigurable() { public function utf8mb4IsConfigurable() {
return TRUE; return TRUE;
} }
@ -579,7 +626,7 @@ class DatabaseConnection_mysql extends DatabaseConnection {
public function utf8mb4IsSupported() { public function utf8mb4IsSupported() {
// Ensure that the MySQL driver supports utf8mb4 encoding. // Ensure that the MySQL driver supports utf8mb4 encoding.
$version = $this->getAttribute(PDO::ATTR_CLIENT_VERSION); $version = $this->connection->getAttribute(PDO::ATTR_CLIENT_VERSION);
if (strpos($version, 'mysqlnd') !== FALSE) { if (strpos($version, 'mysqlnd') !== FALSE) {
// The mysqlnd driver supports utf8mb4 starting at version 5.0.9. // The mysqlnd driver supports utf8mb4 starting at version 5.0.9.
$version = preg_replace('/^\D+([\d.]+).*/', '$1', $version); $version = preg_replace('/^\D+([\d.]+).*/', '$1', $version);

View File

@ -66,11 +66,11 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']); parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
// Force PostgreSQL to use the UTF-8 character set by default. // Force PostgreSQL to use the UTF-8 character set by default.
$this->exec("SET NAMES 'UTF8'"); $this->connection->exec("SET NAMES 'UTF8'");
// Execute PostgreSQL init_commands. // Execute PostgreSQL init_commands.
if (isset($connection_options['init_commands'])) { if (isset($connection_options['init_commands'])) {
$this->exec(implode('; ', $connection_options['init_commands'])); $this->connection->exec(implode('; ', $connection_options['init_commands']));
} }
} }
@ -117,7 +117,7 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
case Database::RETURN_AFFECTED: case Database::RETURN_AFFECTED:
return $stmt->rowCount(); return $stmt->rowCount();
case Database::RETURN_INSERT_ID: case Database::RETURN_INSERT_ID:
return $this->lastInsertId($options['sequence_name']); return $this->connection->lastInsertId($options['sequence_name']);
case Database::RETURN_NULL: case Database::RETURN_NULL:
return; return;
default: default:

View File

@ -964,7 +964,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
*/ */
protected $forUpdate = FALSE; protected $forUpdate = FALSE;
public function __construct($table, $alias = NULL, DatabaseConnection $connection, $options = array()) { public function __construct($table, $alias, DatabaseConnection $connection, $options = array()) {
$options['return'] = Database::RETURN_STATEMENT; $options['return'] = Database::RETURN_STATEMENT;
parent::__construct($connection, $options); parent::__construct($connection, $options);
$this->where = new DatabaseCondition('AND'); $this->where = new DatabaseCondition('AND');

View File

@ -121,7 +121,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
// Execute sqlite init_commands. // Execute sqlite init_commands.
if (isset($connection_options['init_commands'])) { if (isset($connection_options['init_commands'])) {
$this->exec(implode('; ', $connection_options['init_commands'])); $this->connection->exec(implode('; ', $connection_options['init_commands']));
} }
} }
@ -259,7 +259,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
* expose this function to the world. * expose this function to the world.
*/ */
public function PDOPrepare($query, array $options = array()) { public function PDOPrepare($query, array $options = array()) {
return parent::prepare($query, $options); return $this->connection->prepare($query, $options);
} }
public function queryRange($query, $from, $count, array $args = array(), array $options = array()) { public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
@ -350,7 +350,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
} }
} }
if ($this->supportsTransactions()) { if ($this->supportsTransactions()) {
PDO::rollBack(); $this->connection->rollBack();
} }
} }
@ -365,7 +365,7 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
throw new DatabaseTransactionNameNonUniqueException($name . " is already in use."); throw new DatabaseTransactionNameNonUniqueException($name . " is already in use.");
} }
if (!$this->inTransaction()) { if (!$this->inTransaction()) {
PDO::beginTransaction(); $this->connection->beginTransaction();
} }
$this->transactionLayers[$name] = $name; $this->transactionLayers[$name] = $name;
} }
@ -390,9 +390,9 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
// If there was any rollback() we should roll back whole transaction. // If there was any rollback() we should roll back whole transaction.
if ($this->willRollback) { if ($this->willRollback) {
$this->willRollback = FALSE; $this->willRollback = FALSE;
PDO::rollBack(); $this->connection->rollBack();
} }
elseif (!PDO::commit()) { elseif (!$this->connection->commit()) {
throw new DatabaseTransactionCommitFailedException(); throw new DatabaseTransactionCommitFailedException();
} }
} }

View File

@ -48,11 +48,8 @@ function drupal_error_levels() {
* The filename that the error was raised in. * The filename that the error was raised in.
* @param $line * @param $line
* The line number the error was raised at. * The line number the error was raised at.
* @param $context
* An array that points to the active symbol table at the point the error
* occurred.
*/ */
function _drupal_error_handler_real($error_level, $message, $filename, $line, $context) { function _drupal_error_handler_real($error_level, $message, $filename, $line) {
if ($error_level & error_reporting()) { if ($error_level & error_reporting()) {
$types = drupal_error_levels(); $types = drupal_error_levels();
list($severity_msg, $severity_level) = $types[$error_level]; list($severity_msg, $severity_level) = $types[$error_level];

View File

@ -317,7 +317,7 @@ define('MENU_PREFERRED_LINK', '1cf698d64d1aa4b83907cf6ed55db3a7f8e92c91');
* actually exists. This list of 'masks' is built in menu_rebuild(). * actually exists. This list of 'masks' is built in menu_rebuild().
* *
* @param $parts * @param $parts
* An array of path parts; for the above example, * An array of path parts; for the above example,
* array('node', '12345', 'edit'). * array('node', '12345', 'edit').
* *
* @return * @return
@ -2595,7 +2595,7 @@ function menu_get_active_breadcrumb() {
// Don't show a link to the current page in the breadcrumb trail. // Don't show a link to the current page in the breadcrumb trail.
$end = end($active_trail); $end = end($active_trail);
if ($item['href'] == $end['href']) { if (is_array($end) && $item['href'] == $end['href']) {
array_pop($active_trail); array_pop($active_trail);
} }

View File

@ -284,6 +284,20 @@ function drupal_session_start() {
// Save current session data before starting it, as PHP will destroy it. // Save current session data before starting it, as PHP will destroy it.
$session_data = isset($_SESSION) ? $_SESSION : NULL; $session_data = isset($_SESSION) ? $_SESSION : NULL;
// Apply any overrides to the session cookie params.
$params = $original_params = session_get_cookie_params();
// PHP settings for samesite will be handled by _drupal_cookie_params().
unset($params['samesite']);
$params = _drupal_cookie_params($params);
if ($params !== $original_params) {
if (\PHP_VERSION_ID >= 70300) {
session_set_cookie_params($params);
}
else {
session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
}
session_start(); session_start();
drupal_session_started(TRUE); drupal_session_started(TRUE);
@ -323,7 +337,14 @@ function drupal_session_commit() {
$insecure_session_name = substr(session_name(), 1); $insecure_session_name = substr(session_name(), 1);
$params = session_get_cookie_params(); $params = session_get_cookie_params();
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0; $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
setcookie($insecure_session_name, $_COOKIE[$insecure_session_name], $expire, $params['path'], $params['domain'], FALSE, $params['httponly']); $options = array(
'expires' => $expire,
'path' => $params['path'],
'domain' => $params['domain'],
'secure' => FALSE,
'httponly' => $params['httponly'],
);
drupal_setcookie($insecure_session_name, $_COOKIE[$insecure_session_name], $options);
} }
} }
// Write the session data. // Write the session data.
@ -365,7 +386,14 @@ function drupal_session_regenerate() {
// $params['lifetime'] seconds from the current request. If it is not set, // $params['lifetime'] seconds from the current request. If it is not set,
// it will expire when the browser is closed. // it will expire when the browser is closed.
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0; $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
setcookie($insecure_session_name, $session_id, $expire, $params['path'], $params['domain'], FALSE, $params['httponly']); $options = array(
'expires' => $expire,
'path' => $params['path'],
'domain' => $params['domain'],
'secure' => FALSE,
'httponly' => $params['httponly'],
);
drupal_setcookie($insecure_session_name, $session_id, $options);
$_COOKIE[$insecure_session_name] = $session_id; $_COOKIE[$insecure_session_name] = $session_id;
} }
@ -380,7 +408,14 @@ function drupal_session_regenerate() {
if (isset($old_session_id)) { if (isset($old_session_id)) {
$params = session_get_cookie_params(); $params = session_get_cookie_params();
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0; $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
setcookie(session_name(), session_id(), $expire, $params['path'], $params['domain'], $params['secure'], $params['httponly']); $options = array(
'expires' => $expire,
'path' => $params['path'],
'domain' => $params['domain'],
'secure' => $params['secure'],
'httponly' => $params['httponly'],
);
drupal_setcookie(session_name(), session_id(), $options);
$fields = array('sid' => session_id()); $fields = array('sid' => session_id());
if ($is_https) { if ($is_https) {
$fields['ssid'] = session_id(); $fields['ssid'] = session_id();
@ -488,7 +523,14 @@ function _drupal_session_delete_cookie($name, $secure = NULL) {
if ($secure !== NULL) { if ($secure !== NULL) {
$params['secure'] = $secure; $params['secure'] = $secure;
} }
setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']); $options = array(
'expires' => REQUEST_TIME - 3600,
'path' => $params['path'],
'domain' => $params['domain'],
'secure' => $params['secure'],
'httponly' => $params['httponly'],
);
drupal_setcookie($name, '', $options);
unset($_COOKIE[$name]); unset($_COOKIE[$name]);
} }
} }

View File

@ -408,7 +408,7 @@ Drupal.ajax.prototype.beforeSend = function (xmlhttprequest, options) {
// Insert progressbar or throbber. // Insert progressbar or throbber.
if (this.progress.type == 'bar') { if (this.progress.type == 'bar') {
var progressBar = new Drupal.progressBar('ajax-progress-' + this.element.id, eval(this.progress.update_callback), this.progress.method, eval(this.progress.error_callback)); var progressBar = new Drupal.progressBar('ajax-progress-' + this.element.id, $.noop, this.progress.method, $.noop);
if (this.progress.message) { if (this.progress.message) {
progressBar.setProgress(-1, this.progress.message); progressBar.setProgress(-1, this.progress.message);
} }

View File

@ -7,7 +7,7 @@ files[] = aggregator.test
configure = admin/config/services/aggregator/settings configure = admin/config/services/aggregator/settings
stylesheets[all][] = aggregator.css stylesheets[all][] = aggregator.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = block.test files[] = block.test
configure = admin/structure/block configure = admin/structure/block
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -13,7 +13,7 @@ regions[footer] = Footer
regions[highlighted] = Highlighted regions[highlighted] = Highlighted
regions[help] = Help regions[help] = Help
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = blog.test files[] = blog.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ files[] = book.test
configure = admin/content/book/settings configure = admin/content/book/settings
stylesheets[all][] = book.css stylesheets[all][] = book.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -101,7 +101,7 @@ class BookTestCase extends DrupalWebTestCase {
// Check that book pages display along with the correct outlines and // Check that book pages display along with the correct outlines and
// previous/next links. // previous/next links.
$this->checkBookNode($book, array($nodes[0], $nodes[3], $nodes[4]), FALSE, FALSE, $nodes[0], array()); $this->checkBookNode($book, array($nodes[0], $nodes[3], $nodes[4]), FALSE, FALSE, $nodes[0]);
$this->checkBookNode($nodes[0], array($nodes[1], $nodes[2]), $book, $book, $nodes[1], array($book)); $this->checkBookNode($nodes[0], array($nodes[1], $nodes[2]), $book, $book, $nodes[1], array($book));
$this->checkBookNode($nodes[1], NULL, $nodes[0], $nodes[0], $nodes[2], array($book, $nodes[0])); $this->checkBookNode($nodes[1], NULL, $nodes[0], $nodes[0], $nodes[2], array($book, $nodes[0]));
$this->checkBookNode($nodes[2], NULL, $nodes[1], $nodes[0], $nodes[3], array($book, $nodes[0])); $this->checkBookNode($nodes[2], NULL, $nodes[1], $nodes[0], $nodes[3], array($book, $nodes[0]));
@ -124,7 +124,7 @@ class BookTestCase extends DrupalWebTestCase {
// First we must set $this->book to the second book, so that the // First we must set $this->book to the second book, so that the
// correct regex will be generated for testing the outline. // correct regex will be generated for testing the outline.
$this->book = $other_book; $this->book = $other_book;
$this->checkBookNode($other_book, array($node), FALSE, FALSE, $node, array()); $this->checkBookNode($other_book, array($node), FALSE, FALSE, $node);
$this->checkBookNode($node, NULL, $other_book, $other_book, FALSE, array($other_book)); $this->checkBookNode($node, NULL, $other_book, $other_book, FALSE, array($other_book));
} }
@ -144,9 +144,9 @@ class BookTestCase extends DrupalWebTestCase {
* @param $next * @param $next
* (optional) Next link node. Defaults to FALSE. * (optional) Next link node. Defaults to FALSE.
* @param $breadcrumb * @param $breadcrumb
* The nodes that should be displayed in the breadcrumb. * (optional) The nodes that should be displayed in the breadcrumb.
*/ */
function checkBookNode($node, $nodes, $previous = FALSE, $up = FALSE, $next = FALSE, array $breadcrumb) { function checkBookNode($node, $nodes = NULL, $previous = FALSE, $up = FALSE, $next = FALSE, array $breadcrumb = array()) {
// $number does not use drupal_static as it should not be reset // $number does not use drupal_static as it should not be reset
// since it uniquely identifies each call to checkBookNode(). // since it uniquely identifies each call to checkBookNode().
static $number = 0; static $number = 0;

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = color.test files[] = color.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -9,7 +9,7 @@ files[] = comment.test
configure = admin/content/comment configure = admin/content/comment
stylesheets[all][] = comment.css stylesheets[all][] = comment.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = contact.test files[] = contact.test
configure = admin/structure/contact configure = admin/structure/contact
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = contextual.test files[] = contextual.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ files[] = dashboard.test
dependencies[] = block dependencies[] = block
configure = admin/dashboard/customize configure = admin/dashboard/customize
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = dblog.test files[] = dblog.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -11,7 +11,7 @@ dependencies[] = field_sql_storage
required = TRUE required = TRUE
stylesheets[all][] = theme/field.css stylesheets[all][] = theme/field.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ dependencies[] = field
files[] = field_sql_storage.test files[] = field_sql_storage.test
required = TRUE required = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -434,6 +434,81 @@ function field_sql_storage_field_storage_load($entity_type, $entities, $age, $fi
} }
} }
/**
* Callback for array_filter().
*/
function _field_sql_storage_write_compare_filter_callback($value) {
return NULL !== $value && '' !== $value;
}
/**
* Cleanup field values for later values comparison.
*
* @param array $field
* Field info as returned by field_info_field_by_id().
*
* @param array $array
* Field values to cleanup.
*
* @return array
* Filtered values.
*/
function _field_sql_storage_write_compare_filter($field, $array) {
foreach ($array as $language => $items) {
if (empty($items)) {
unset($array[$language]);
}
else {
foreach ($items as $delta => $item) {
// This should not happen but some modules provide invalid data to the
// field API.
if (!is_array($item)) {
continue;
}
// Let's start by pruning empty values and non storable values.
$array[$language][$delta] = array_filter(array_intersect_key($item, $field['columns']), '_field_sql_storage_write_compare_filter_callback');
// Ordering is important because for widget elements and loaded columns
// from database order might differ and give false positives on field
// value change, especially with complex fields such as image fields.
ksort($array[$language][$delta]);
}
}
}
return $array;
}
/**
* Compare a single field value for both entities and tell us if it changed.
*
* @param array $field
* Loaded field structure.
* @param object $entity1
* First entity to compare.
* @param object $entity2
* Second entity to compare.
*
* @return bool
* True if field value changed, false otherwise.
*/
function _field_sql_storage_write_compare($field, $entity1, $entity2) {
$field_name = $field['field_name'];
if (empty($entity1->$field_name) && empty($entity2->$field_name)) {
// Both are empty we can safely assume that it did not change.
return FALSE;
}
if (!isset($entity1->$field_name) || !isset($entity2->$field_name)) {
// One of them is missing but not the other the value changed.
return TRUE;
}
// We need to proceed to deep array comparison, but we cannot do it naively:
// in most cases the field values come from the edit form, and some Form API
// widget values that are not field columns may be present. We need to clean
// up both original and new field values before comparison.
$items1 = _field_sql_storage_write_compare_filter($field, (array) $entity1->$field_name);
$items2 = _field_sql_storage_write_compare_filter($field, (array) $entity2->$field_name);
return $items1 != $items2;
}
/** /**
* Implements hook_field_storage_write(). * Implements hook_field_storage_write().
*/ */
@ -443,8 +518,29 @@ function field_sql_storage_field_storage_write($entity_type, $entity, $op, $fiel
$vid = $id; $vid = $id;
} }
// Check if the given entity is a new revision or not. In case of a new
// revision creation, we cannot skip any field.
if (!empty($vid) && !empty($entity->original)) {
list(, $original_vid) = entity_extract_ids($entity_type, $entity->original);
if (NULL === $original_vid) {
$original_vid = $id;
}
$is_new_revision = $original_vid != $vid;
}
else {
$is_new_revision = FALSE;
}
// Allow this optimization to be optional.
$skip_unchanged_fields = variable_get('field_sql_storage_skip_writing_unchanged_fields', FALSE);
foreach ($fields as $field_id) { foreach ($fields as $field_id) {
$field = field_info_field_by_id($field_id); $field = field_info_field_by_id($field_id);
if ($skip_unchanged_fields && !$is_new_revision && !empty($entity->original) && !_field_sql_storage_write_compare($field, $entity, $entity->original)) {
continue;
}
$field_name = $field['field_name']; $field_name = $field['field_name'];
$table_name = _field_sql_storage_tablename($field); $table_name = _field_sql_storage_tablename($field);
$revision_name = _field_sql_storage_revision_tablename($field); $revision_name = _field_sql_storage_revision_tablename($field);

View File

@ -281,6 +281,69 @@ class FieldSqlStorageTestCase extends DrupalWebTestCase {
$this->assertEqual($count, 1, 'NULL field translation is wiped.'); $this->assertEqual($count, 1, 'NULL field translation is wiped.');
} }
/**
* Tests the expected return values of _field_sql_storage_write_compare().
*/
public function testFieldCompareDataModification() {
$langcode = LANGUAGE_NONE;
$field_info = field_info_field($this->field_name);
// Make sure we have 2 sample field values that are unique.
$value1 = 0;
$value2 = 0;
while ($value1 == $value2) {
$value1 = mt_rand();
$value2 = (string) mt_rand();
}
// Create the 2 entities to compare.
$entity = field_test_create_stub_entity();
$entity->{$this->field_name}[$langcode][]['value'] = $value1;
$entity1 = clone $entity;
$entity2 = clone $entity;
// Make sure that it correctly compares identical entities.
$this->assert(!_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'The entities are identical.');
// Compare to an empty object.
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, new stdClass()), 'The entity is not the same as an empty object.');
// Change one of the values.
$entity2->{$this->field_name}[$langcode][0]['value'] = $value2;
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'The values are not the same.');
// Reset $entity2.
$entity2 = clone $entity;
// Duplicate the value on one of the entities.
$entity1->{$this->field_name}[$langcode][]['value'] = $value1;
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'The fields do not have the same number of values.');
// Add a second value to both entities.
$entity2->{$this->field_name}[$langcode][]['value'] = $value2;
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'The values are not the same.');
// Replace the array containing the value with the actual value.
$entity2->{$this->field_name}[$langcode] = $entity2->{$this->field_name}[$langcode][0];
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'The array to hold field values is replaced by the value.');
// Null one value.
$entity2->{$this->field_name}[$langcode] = NULL;
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'One field is NULL and the other is not.');
// Null both values.
$entity1->{$this->field_name}[$langcode] = NULL;
$this->assert(!_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'Both fields are NULL.');
// Unset one of the fields.
unset($entity2->{$this->field_name});
$this->assert(_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'One field structure is unset.');
// Unset both of the fields.
unset($entity1->{$this->field_name});
$this->assert(!_field_sql_storage_write_compare($field_info, $entity1, $entity2), 'Both field structures are unset.');
}
/** /**
* Test trying to update a field with data. * Test trying to update a field with data.
*/ */

View File

@ -7,7 +7,7 @@ dependencies[] = field
dependencies[] = options dependencies[] = options
files[] = tests/list.test files[] = tests/list.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = field dependencies[] = field
files[] = number.test files[] = number.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = field dependencies[] = field
files[] = options.test files[] = options.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ dependencies[] = field
files[] = text.test files[] = text.test
required = TRUE required = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ files[] = field_test.entity.inc
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -240,111 +240,6 @@ function field_test_field_storage_delete_revision($entity_type, $entity, $fields
_field_test_storage_data($data); _field_test_storage_data($data);
} }
/**
* Implements hook_field_storage_query().
*/
function field_test_field_storage_query($field_id, $conditions, $count, &$cursor = NULL, $age) {
$data = _field_test_storage_data();
$load_current = $age == FIELD_LOAD_CURRENT;
$field = field_info_field_by_id($field_id);
$field_columns = array_keys($field['columns']);
$field_data = $data[$field['id']];
$sub_table = $load_current ? 'current' : 'revisions';
// We need to sort records by entity type and entity id.
usort($field_data[$sub_table], '_field_test_field_storage_query_sort_helper');
// Initialize results array.
$return = array();
$entity_count = 0;
$rows_count = 0;
$rows_total = count($field_data[$sub_table]);
$skip = $cursor;
$skipped = 0;
foreach ($field_data[$sub_table] as $row) {
if ($count != FIELD_QUERY_NO_LIMIT && $entity_count >= $count) {
break;
}
if ($row->field_id == $field['id']) {
$match = TRUE;
$condition_deleted = FALSE;
// Add conditions.
foreach ($conditions as $condition) {
@list($column, $value, $operator) = $condition;
if (empty($operator)) {
$operator = is_array($value) ? 'IN' : '=';
}
switch ($operator) {
case '=':
$match = $match && $row->{$column} == $value;
break;
case '<>':
case '<':
case '<=':
case '>':
case '>=':
eval('$match = $match && ' . $row->{$column} . ' ' . $operator . ' '. $value);
break;
case 'IN':
$match = $match && in_array($row->{$column}, $value);
break;
case 'NOT IN':
$match = $match && !in_array($row->{$column}, $value);
break;
case 'BETWEEN':
$match = $match && $row->{$column} >= $value[0] && $row->{$column} <= $value[1];
break;
case 'STARTS_WITH':
case 'ENDS_WITH':
case 'CONTAINS':
// Not supported.
$match = FALSE;
break;
}
// Track condition on 'deleted'.
if ($column == 'deleted') {
$condition_deleted = TRUE;
}
}
// Exclude deleted data unless we have a condition on it.
if (!$condition_deleted && $row->deleted) {
$match = FALSE;
}
if ($match) {
if (!isset($skip) || $skipped >= $skip) {
$cursor++;
// If querying all revisions and the entity type has revisions, we need
// to key the results by revision_ids.
$entity_type = entity_get_info($row->type);
$id = ($load_current || empty($entity_type['entity keys']['revision'])) ? $row->entity_id : $row->revision_id;
if (!isset($return[$row->type][$id])) {
$return[$row->type][$id] = entity_create_stub_entity($row->type, array($row->entity_id, $row->revision_id, $row->bundle));
$entity_count++;
}
}
else {
$skipped++;
}
}
}
$rows_count++;
// The query is complete if we walked the whole array.
if ($count != FIELD_QUERY_NO_LIMIT && $rows_count >= $rows_total) {
$cursor = FIELD_QUERY_COMPLETE;
}
}
return $return;
}
/** /**
* Sort helper for field_test_field_storage_query(). * Sort helper for field_test_field_storage_query().
* *

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = field dependencies[] = field
files[] = field_ui.test files[] = field_ui.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -593,7 +593,7 @@ function file_field_widget_uri($field, $instance, $data = array()) {
/** /**
* The #value_callback for the file_generic field element. * The #value_callback for the file_generic field element.
*/ */
function file_field_widget_value($element, $input = FALSE, $form_state) { function file_field_widget_value($element, $input = FALSE, $form_state = array()) {
if ($input) { if ($input) {
// Checkboxes lose their value when empty. // Checkboxes lose their value when empty.
// If the display field is present make sure its unchecked value is saved. // If the display field is present make sure its unchecked value is saved.
@ -955,17 +955,14 @@ function theme_file_upload_help($variables) {
if (isset($upload_validators['file_validate_image_resolution'])) { if (isset($upload_validators['file_validate_image_resolution'])) {
$max = $upload_validators['file_validate_image_resolution'][0]; $max = $upload_validators['file_validate_image_resolution'][0];
$min = $upload_validators['file_validate_image_resolution'][1]; $min = $upload_validators['file_validate_image_resolution'][1];
if ($min && $max && $min == $max) { if ($min && $max) {
$descriptions[] = t('Images must be exactly !size pixels.', array('!size' => '<strong>' . $max . '</strong>')); $descriptions[] = t('Images must be at least !min pixels. Images larger than !max pixels will be resized.', array('!min' => '<strong>' . $min . '</strong>', '!max' => '<strong>' . $max . '</strong>'));
}
elseif ($min && $max) {
$descriptions[] = t('Images must be between !min and !max pixels.', array('!min' => '<strong>' . $min . '</strong>', '!max' => '<strong>' . $max . '</strong>'));
} }
elseif ($min) { elseif ($min) {
$descriptions[] = t('Images must be larger than !min pixels.', array('!min' => '<strong>' . $min . '</strong>')); $descriptions[] = t('Images must be at least !min pixels.', array('!min' => '<strong>' . $min . '</strong>'));
} }
elseif ($max) { elseif ($max) {
$descriptions[] = t('Images must be smaller than !max pixels.', array('!max' => '<strong>' . $max . '</strong>')); $descriptions[] = t('Images larger than !max pixels will be resized.', array('!max' => '<strong>' . $max . '</strong>'));
} }
} }

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = field dependencies[] = field
files[] = tests/file.test files[] = tests/file.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ files[] = filter.test
required = TRUE required = TRUE
configure = admin/config/content/formats configure = admin/config/content/formats
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -9,7 +9,7 @@ files[] = forum.test
configure = admin/structure/forum configure = admin/structure/forum
stylesheets[all][] = forum.css stylesheets[all][] = forum.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = help.test files[] = help.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -7,7 +7,7 @@ dependencies[] = file
files[] = image.test files[] = image.test
configure = admin/config/media/image-styles configure = admin/config/media/image-styles
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -1022,7 +1022,7 @@ class ImageFieldDisplayTestCase extends ImageFieldTestCase {
$this->drupalGet('node/add/article'); $this->drupalGet('node/add/article');
$this->assertText(t('Files must be less than 50 KB.'), 'Image widget max file size is displayed on article form.'); $this->assertText(t('Files must be less than 50 KB.'), 'Image widget max file size is displayed on article form.');
$this->assertText(t('Allowed file types: ' . $test_image_extension . '.'), 'Image widget allowed file types displayed on article form.'); $this->assertText(t('Allowed file types: ' . $test_image_extension . '.'), 'Image widget allowed file types displayed on article form.');
$this->assertText(t('Images must be between 10x10 and 100x100 pixels.'), 'Image widget allowed resolution displayed on article form.'); $this->assertText(t('Images must be at least 10x10 pixels. Images larger than 100x100 pixels will be resized.'), 'Image widget allowed resolution displayed on article form.');
// We have to create the article first and then edit it because the alt // We have to create the article first and then edit it because the alt
// and title fields do not display until the image has been attached. // and title fields do not display until the image has been attached.

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = image_module_test.module files[] = image_module_test.module
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = locale.test files[] = locale.test
configure = admin/config/regional/language configure = admin/config/regional/language
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = menu.test files[] = menu.test
configure = admin/structure/menu configure = admin/structure/menu
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -9,7 +9,7 @@ required = TRUE
configure = admin/structure/types configure = admin/structure/types
stylesheets[all][] = node.css stylesheets[all][] = node.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -142,7 +142,8 @@ function _openid_xrds_parse($raw_xml) {
// For PHP version >= 5.2.11, we can use this function to protect against // For PHP version >= 5.2.11, we can use this function to protect against
// malicious doctype declarations and other unexpected entity loading. // malicious doctype declarations and other unexpected entity loading.
// However, we will not rely on it, and reject any XML with a DOCTYPE. // However, we will not rely on it, and reject any XML with a DOCTYPE.
$disable_entity_loader = function_exists('libxml_disable_entity_loader'); // libxml_disable_entity_loader() is deprecated in PHP >= 8.0.
$disable_entity_loader = function_exists('libxml_disable_entity_loader') && PHP_VERSION_ID < 80000;
if ($disable_entity_loader) { if ($disable_entity_loader) {
$load_entities = libxml_disable_entity_loader(TRUE); $load_entities = libxml_disable_entity_loader(TRUE);
} }

View File

@ -5,7 +5,7 @@ package = Core
core = 7.x core = 7.x
files[] = openid.test files[] = openid.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -743,7 +743,7 @@ function openid_association_request($public) {
return $request; return $request;
} }
function openid_authentication_request($claimed_id, $identity, $return_to = '', $assoc_handle = '', $service) { function openid_authentication_request($claimed_id, $identity, $return_to, $assoc_handle, $service) {
global $base_url; global $base_url;
module_load_include('inc', 'openid'); module_load_include('inc', 'openid');

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = openid dependencies[] = openid
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -4,7 +4,7 @@ package = Core
version = VERSION version = VERSION
core = 7.x core = 7.x
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = path.test files[] = path.test
configure = admin/config/search/path configure = admin/config/search/path
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = php.test files[] = php.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = poll.test files[] = poll.test
stylesheets[all][] = poll.css stylesheets[all][] = poll.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -11,7 +11,7 @@ configure = admin/config/people/profile
; See user_system_info_alter(). ; See user_system_info_alter().
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
files[] = rdf.test files[] = rdf.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
hidden = TRUE hidden = TRUE
dependencies[] = blog dependencies[] = blog
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -8,7 +8,7 @@ files[] = search.test
configure = admin/config/search/settings configure = admin/config/search/settings
stylesheets[all][] = search.css stylesheets[all][] = search.css
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = shortcut.test files[] = shortcut.test
configure = admin/config/user-interface/shortcut configure = admin/config/user-interface/shortcut
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -1690,8 +1690,14 @@ class DrupalWebTestCase extends DrupalTestCase {
$this->fail('Failed to drop all prefixed tables.'); $this->fail('Failed to drop all prefixed tables.');
} }
// In PHP 8 some tests encounter problems when shutdown code tries to
// access the database connection after it's been explicitly closed, for
// example the destructor of DrupalCacheArray. We avoid this by not fully
// destroying the test database connection.
$close = \PHP_VERSION_ID < 80000;
// Get back to the original connection. // Get back to the original connection.
Database::removeConnection('default'); Database::removeConnection('default', $close);
Database::renameConnection('simpletest_original_default', 'default'); Database::renameConnection('simpletest_original_default', 'default');
// Restore original shutdown callbacks array to prevent original // Restore original shutdown callbacks array to prevent original
@ -3084,7 +3090,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* @return * @return
* TRUE on pass, FALSE on fail. * TRUE on pass, FALSE on fail.
*/ */
protected function assertTextHelper($text, $message = '', $group, $not_exists) { protected function assertTextHelper($text, $message, $group, $not_exists) {
if ($this->plainTextContent === FALSE) { if ($this->plainTextContent === FALSE) {
$this->plainTextContent = filter_xss($this->drupalGetContent(), array()); $this->plainTextContent = filter_xss($this->drupalGetContent(), array());
} }
@ -3150,7 +3156,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* @return * @return
* TRUE on pass, FALSE on fail. * TRUE on pass, FALSE on fail.
*/ */
protected function assertUniqueTextHelper($text, $message = '', $group, $be_unique) { protected function assertUniqueTextHelper($text, $message, $group, $be_unique) {
if ($this->plainTextContent === FALSE) { if ($this->plainTextContent === FALSE) {
$this->plainTextContent = filter_xss($this->drupalGetContent(), array()); $this->plainTextContent = filter_xss($this->drupalGetContent(), array());
} }
@ -3256,7 +3262,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* @param $callback * @param $callback
* The name of the theme function to invoke; e.g. 'links' for theme_links(). * The name of the theme function to invoke; e.g. 'links' for theme_links().
* @param $variables * @param $variables
* (optional) An array of variables to pass to the theme function. * An array of variables to pass to the theme function.
* @param $expected * @param $expected
* The expected themed output string. * The expected themed output string.
* @param $message * @param $message
@ -3272,7 +3278,7 @@ class DrupalWebTestCase extends DrupalTestCase {
* @return * @return
* TRUE on pass, FALSE on fail. * TRUE on pass, FALSE on fail.
*/ */
protected function assertThemeOutput($callback, array $variables = array(), $expected, $message = '', $group = 'Other') { protected function assertThemeOutput($callback, array $variables, $expected, $message = '', $group = 'Other') {
$output = theme($callback, $variables); $output = theme($callback, $variables);
$this->verbose('Variables:' . '<pre>' . check_plain(var_export($variables, TRUE)) . '</pre>' $this->verbose('Variables:' . '<pre>' . check_plain(var_export($variables, TRUE)) . '</pre>'
. '<hr />' . 'Result:' . '<pre>' . check_plain(var_export($output, TRUE)) . '</pre>' . '<hr />' . 'Result:' . '<pre>' . check_plain(var_export($output, TRUE)) . '</pre>'

View File

@ -58,7 +58,7 @@ files[] = tests/upgrade/update.trigger.test
files[] = tests/upgrade/update.field.test files[] = tests/upgrade/update.field.test
files[] = tests/upgrade/update.user.test files[] = tests/upgrade/update.user.test
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -164,13 +164,16 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
$this->pass(t('Test ID is @id.', array('@id' => $this->testId))); $this->pass(t('Test ID is @id.', array('@id' => $this->testId)));
// Generates a warning. // Generates a warning.
$i = 1 / 0; $a = '';
foreach ($a as $b) {
}
// Call an assert function specific to that class. // Call an assert function specific to that class.
$this->assertNothing(); $this->assertNothing();
// Generates a warning inside a PHP function. // Generates 3 warnings inside a PHP function.
array_key_exists(NULL, NULL); simplexml_load_string('<fake>');
debug('Foo', 'Debug'); debug('Foo', 'Debug');
} }
@ -195,19 +198,21 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
$this->assertAssertion(t('Invalid permission %permission.', array('%permission' => $this->invalid_permission)), 'Role', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); $this->assertAssertion(t('Invalid permission %permission.', array('%permission' => $this->invalid_permission)), 'Role', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
// Check that a warning is caught by simpletest. // Check that a warning is caught by simpletest.
$this->assertAssertion('Division by zero', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); // The exact error message differs between PHP versions so we check only
// the presense of the 'foreach' statement.
$this->assertAssertion('foreach()', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
// Check that the backtracing code works for specific assert function. // Check that the backtracing code works for specific assert function.
$this->assertAssertion('This is nothing.', 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); $this->assertAssertion('This is nothing.', 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
// Check that errors that occur inside PHP internal functions are correctly reported. // Check that errors that occur inside PHP internal functions are correctly reported.
// The exact error message differs between PHP versions so we check only // The exact error message differs between PHP versions so we check only
// the function name 'array_key_exists'. // the function name 'simplexml_load_string'.
$this->assertAssertion('array_key_exists', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); $this->assertAssertion('simplexml_load_string', 'Warning', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
$this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); $this->assertAssertion("Debug: 'Foo'", 'Debug', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()');
$this->assertEqual('6 passes, 5 fails, 2 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct'); $this->assertEqual('6 passes, 5 fails, 4 exceptions, and 1 debug message', $this->childTestResults['summary'], 'Stub test summary is correct');
$this->test_ids[] = $test_id = $this->getTestIdFromResults(); $this->test_ids[] = $test_id = $this->getTestIdFromResults();
$this->assertTrue($test_id, 'Found test ID in results.'); $this->assertTrue($test_id, 'Found test ID in results.');

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -453,13 +453,13 @@ class BootstrapGetFilenameTestCase extends DrupalUnitTestCase {
/** /**
* Skips handling of "file not found" errors. * Skips handling of "file not found" errors.
*/ */
public function fileNotFoundErrorHandler($error_level, $message, $filename, $line, $context) { public function fileNotFoundErrorHandler($error_level, $message, $filename, $line) {
// Skip error handling if this is a "file not found" error. // Skip error handling if this is a "file not found" error.
if (strpos($message, 'is missing from the file system:') !== FALSE || strpos($message, 'has moved within the file system:') !== FALSE) { if (strpos($message, 'is missing from the file system:') !== FALSE || strpos($message, 'has moved within the file system:') !== FALSE) {
$this->getFilenameTestTriggeredError = $message; $this->getFilenameTestTriggeredError = $message;
return; return;
} }
_drupal_error_handler($error_level, $message, $filename, $line, $context); _drupal_error_handler($error_level, $message, $filename, $line);
} }
} }
@ -569,13 +569,13 @@ class BootstrapGetFilenameWebTestCase extends DrupalWebTestCase {
/** /**
* Skips handling of "file not found" errors. * Skips handling of "file not found" errors.
*/ */
public function fileNotFoundErrorHandler($error_level, $message, $filename, $line, $context) { public function fileNotFoundErrorHandler($error_level, $message, $filename, $line) {
// Skip error handling if this is a "file not found" error. // Skip error handling if this is a "file not found" error.
if (strpos($message, 'is missing from the file system:') !== FALSE || strpos($message, 'has moved within the file system:') !== FALSE) { if (strpos($message, 'is missing from the file system:') !== FALSE || strpos($message, 'has moved within the file system:') !== FALSE) {
$this->getFilenameTestTriggeredError = $message; $this->getFilenameTestTriggeredError = $message;
return; return;
} }
_drupal_error_handler($error_level, $message, $filename, $line, $context); _drupal_error_handler($error_level, $message, $filename, $line);
} }
/** /**

View File

@ -2633,8 +2633,8 @@ class DrupalErrorCollectionUnitTest extends DrupalWebTestCase {
$this->assertEqual(count($this->collectedErrors), 3, 'Three errors were collected'); $this->assertEqual(count($this->collectedErrors), 3, 'Three errors were collected');
if (count($this->collectedErrors) == 3) { if (count($this->collectedErrors) == 3) {
$this->assertError($this->collectedErrors[0], 'Notice', 'error_test_generate_warnings()', 'error_test.module', 'Undefined variable: bananas'); $this->assertError($this->collectedErrors[0], 'Notice', 'error_test_generate_warnings()', 'error_test.module', 'Object of class stdClass could not be converted to int');
$this->assertError($this->collectedErrors[1], 'Warning', 'error_test_generate_warnings()', 'error_test.module', 'Division by zero'); $this->assertError($this->collectedErrors[1], 'Warning', 'error_test_generate_warnings()', 'error_test.module', \PHP_VERSION_ID < 80000 ? 'Invalid argument supplied for foreach()' : 'foreach() argument must be of type array|object, string given');
$this->assertError($this->collectedErrors[2], 'User warning', 'error_test_generate_warnings()', 'error_test.module', 'Drupal is awesome'); $this->assertError($this->collectedErrors[2], 'User warning', 'error_test_generate_warnings()', 'error_test.module', 'Drupal is awesome');
} }
else { else {

View File

@ -7,7 +7,7 @@ stylesheets[all][] = common_test.css
stylesheets[print][] = common_test.print.css stylesheets[print][] = common_test.print.css
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -3755,21 +3755,36 @@ class DatabaseTransactionTestCase extends DatabaseTestCase {
$transaction = db_transaction(); $transaction = db_transaction();
$this->insertRow('row'); $this->insertRow('row');
$this->executeDDLStatement(); $this->executeDDLStatement();
// Rollback the outer transaction.
set_error_handler(array($this, 'rollBackWithoutTransactionErrorHandler'));
try { try {
// Rollback the outer transaction.
$transaction->rollback(); $transaction->rollback();
unset($transaction); // @see \DatabaseConnection_mysql::rollback()
// @TODO: an exception should be triggered here, but is not, because if (PHP_VERSION_ID >= 80000) {
// "ROLLBACK" fails silently in MySQL if there is no transaction active. $this->fail('Rolling back a transaction containing DDL should produce a warning.');
// $this->fail(t('Rolling back a transaction containing DDL should fail.')); }
} }
catch (DatabaseTransactionNoActiveException $e) { catch (Exception $e) {
$this->pass('Rolling back a transaction containing DDL should fail.'); $this->assertEqual('Rollback attempted when there is no active transaction.', $e->getMessage());
} }
restore_error_handler();
unset($transaction);
$this->assertRowPresent('row'); $this->assertRowPresent('row');
} }
} }
/**
* Special handling of "rollback without transaction" errors.
*/
public function rollBackWithoutTransactionErrorHandler($error_level, $message, $filename, $line) {
// Throw an exception if this is a "rollback without transaction" error.
if (strpos($message, 'Rollback attempted when there is no active transaction.') !== FALSE ) {
throw new Exception('Rollback attempted when there is no active transaction.');
}
_drupal_error_handler($error_level, $message, $filename, $line);
}
/** /**
* Insert a single row into the testing table. * Insert a single row into the testing table.
*/ */

View File

@ -7,7 +7,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -6,7 +6,7 @@ core = 7.x
dependencies[] = entity_cache_test_dependency dependencies[] = entity_cache_test_dependency
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ package = Testing
version = VERSION version = VERSION
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -22,13 +22,13 @@ class DrupalErrorHandlerTestCase extends DrupalWebTestCase {
function testErrorHandler() { function testErrorHandler() {
$error_notice = array( $error_notice = array(
'%type' => 'Notice', '%type' => 'Notice',
'!message' => 'Undefined variable: bananas', '!message' => 'Object of class stdClass could not be converted to int',
'%function' => 'error_test_generate_warnings()', '%function' => 'error_test_generate_warnings()',
'%file' => drupal_realpath('modules/simpletest/tests/error_test.module'), '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
); );
$error_warning = array( $error_warning = array(
'%type' => 'Warning', '%type' => 'Warning',
'!message' => 'Division by zero', '!message' => \PHP_VERSION_ID < 80000 ? 'Invalid argument supplied for foreach()' : 'foreach() argument must be of type array|object, string given',
'%function' => 'error_test_generate_warnings()', '%function' => 'error_test_generate_warnings()',
'%file' => drupal_realpath('modules/simpletest/tests/error_test.module'), '%file' => drupal_realpath('modules/simpletest/tests/error_test.module'),
); );
@ -113,4 +113,3 @@ class DrupalErrorHandlerTestCase extends DrupalWebTestCase {
$this->assertNoRaw($message, format_string('Did not find error message: !message.', array('!message' => $message))); $this->assertNoRaw($message, format_string('Did not find error message: !message.', array('!message' => $message)));
} }
} }

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -40,9 +40,13 @@ function error_test_generate_warnings($collect_errors = FALSE) {
// Tell Drupal error reporter to send errors to Simpletest or not. // Tell Drupal error reporter to send errors to Simpletest or not.
define('SIMPLETEST_COLLECT_ERRORS', $collect_errors); define('SIMPLETEST_COLLECT_ERRORS', $collect_errors);
// This will generate a notice. // This will generate a notice.
$monkey_love = $bananas; $notice = new \stdClass();
$notice == 1 ? 1 : 0;
// This will generate a warning. // This will generate a warning.
$awesomely_big = 1/0; $a = '';
foreach ($a as $b) {
}
// This will generate a user error. // This will generate a user error.
trigger_error("Drupal is awesome", E_USER_WARNING); trigger_error("Drupal is awesome", E_USER_WARNING);
return ""; return "";

View File

@ -6,7 +6,7 @@ core = 7.x
files[] = file_test.module files[] = file_test.module
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -240,14 +240,14 @@ class FormsTestCase extends DrupalWebTestCase {
$values = drupal_json_decode($this->drupalPost(NULL, array('required_checkbox' => 1), t('Submit'))); $values = drupal_json_decode($this->drupalPost(NULL, array('required_checkbox' => 1), t('Submit')));
$expected_values = array( $expected_values = array(
'disabled_checkbox_on' => 'disabled_checkbox_on', 'disabled_checkbox_on' => 'disabled_checkbox_on',
'disabled_checkbox_off' => '', 'disabled_checkbox_off' => 0,
'checkbox_on' => 'checkbox_on', 'checkbox_on' => 'checkbox_on',
'checkbox_off' => '', 'checkbox_off' => 0,
'zero_checkbox_on' => '0', 'zero_checkbox_on' => '0',
'zero_checkbox_off' => '', 'zero_checkbox_off' => 0,
); );
foreach ($expected_values as $widget => $expected_value) { foreach ($expected_values as $widget => $expected_value) {
$this->assertEqual($values[$widget], $expected_value, format_string('Checkbox %widget returns expected value (expected: %expected, got: %value)', array( $this->assertIdentical($values[$widget], $expected_value, format_string('Checkbox %widget returns expected value (expected: %expected, got: %value)', array(
'%widget' => var_export($widget, TRUE), '%widget' => var_export($widget, TRUE),
'%expected' => var_export($expected_value, TRUE), '%expected' => var_export($expected_value, TRUE),
'%value' => var_export($values[$widget], TRUE), '%value' => var_export($values[$widget], TRUE),

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

View File

@ -5,7 +5,7 @@ version = VERSION
core = 7.x core = 7.x
hidden = TRUE hidden = TRUE
; Information added by Drupal.org packaging script on 2021-01-20 ; Information added by Drupal.org packaging script on 2021-04-21
version = "7.78" version = "7.80"
project = "drupal" project = "drupal"
datestamp = "1611162699" datestamp = "1619021862"

Some files were not shown because too many files have changed in this diff Show More