Update Drupal 7 dependencies

This commit is contained in:
Mauricio Dinarte 2025-06-03 10:37:00 -06:00 committed by Janez Urevc
parent 7d902ba1ef
commit 13df912654
391 changed files with 2900 additions and 1502 deletions

View file

@ -323,7 +323,7 @@ function ajax_render($commands = array()) {
function ajax_get_form() {
$form_state = form_state_defaults();
$form_build_id = $_POST['form_build_id'];
$form_build_id = (isset($_POST['form_build_id']) ? $_POST['form_build_id'] : '');
// Get the form from the cache.
$form = form_get_cache($form_build_id, $form_state);

View file

@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.100');
define('VERSION', '7.103');
/**
* Core API compatibility.
@ -729,8 +729,8 @@ function drupal_environment_initialize() {
/**
* Validates that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
*
* @return
* TRUE if only containing valid characters, or FALSE otherwise.
* @return bool
* TRUE if it only contains valid characters, FALSE otherwise.
*/
function drupal_valid_http_host($host) {
// Limit the length of the host name to 1000 bytes to prevent DoS attacks with
@ -807,8 +807,8 @@ function drupal_settings_initialize() {
// Otherwise use $base_url as session name, without the protocol
// to use the same session identifiers across HTTP and HTTPS.
list( , $session_name) = explode('://', $base_url, 2);
// HTTP_HOST can be modified by a visitor, but we already sanitized it
// in drupal_settings_initialize().
// HTTP_HOST can be modified by a visitor, but we already sanitized it in
// drupal_environment_initialize().
if (!empty($_SERVER['HTTP_HOST'])) {
$cookie_domain = _drupal_get_cookie_domain($_SERVER['HTTP_HOST']);
}
@ -2285,7 +2285,8 @@ function drupal_block_denied($ip) {
* The number of random bytes to fetch and base64 encode.
*
* @return string
* The base64 encoded result will have a length of up to 4 * $byte_count.
* A base-64 encoded string, with + replaced with -, / with _ and any =
* padding characters removed.
*/
function drupal_random_key($byte_count = 32) {
return drupal_base64_encode(drupal_random_bytes($byte_count));
@ -2718,6 +2719,18 @@ function _drupal_bootstrap_configuration() {
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
// Check trusted HTTP Host headers to protect against header attacks.
if (PHP_SAPI !== 'cli') {
$host_patterns = variable_get('trusted_host_patterns', array());
if (!empty($host_patterns)) {
if (!drupal_check_trusted_hosts($_SERVER['HTTP_HOST'], $host_patterns)) {
header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
print 'The provided host name is not valid for this server.';
exit;
}
}
}
// Sanitize unsafe keys from the request.
DrupalRequestSanitizer::sanitize();
}
@ -3947,6 +3960,36 @@ function drupal_clear_opcode_cache($filepath) {
}
}
/**
* Checks trusted HTTP Host headers to protect against header injection attacks.
*
* @param string|null $host
* The host name.
* @param array $host_patterns
* The array of trusted host patterns.
*
* @return bool
* TRUE if the host is trusted, FALSE otherwise.
*/
function drupal_check_trusted_hosts($host, array $host_patterns) {
if (!empty($host) && !empty($host_patterns)) {
// Trim and remove the port number from host; host is lowercase as per
// RFC 952/2181.
$host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
foreach ($host_patterns as $pattern) {
$pattern = sprintf('{%s}i', $pattern);
if (preg_match($pattern, $host)) {
return TRUE;
}
}
return FALSE;
}
return TRUE;
}
/**
* Drupal's wrapper around PHP's setcookie() function.
*

View file

@ -2967,7 +2967,11 @@ function drupal_set_time_limit($time_limit) {
* The path to the requested item or an empty string if the item is not found.
*/
function drupal_get_path($type, $name) {
return dirname(drupal_get_filename($type, $name));
if ($filename = drupal_get_filename($type, $name)) {
return dirname($filename);
}
return "";
}
/**
@ -5544,8 +5548,27 @@ function drupal_cron_run() {
DrupalQueue::get($queue_name)->createQueue();
}
$module_previous = '';
// If detailed logging isn't enabled, don't log individual execution times.
$time_logging_enabled = variable_get('cron_detailed_logging', DRUPAL_CRON_DETAILED_LOGGING);
// Iterate through the modules calling their cron handlers (if any):
foreach (module_implements('cron') as $module) {
if ($time_logging_enabled) {
if (!$module_previous) {
watchdog('cron', 'Starting execution of @module_cron().', array('@module' => $module));
}
else {
watchdog('cron', 'Starting execution of @module_cron(), execution of @module_previous_cron() took @time.', array(
'@module' => $module,
'@module_previous' => $module_previous,
'@time' => timer_read('cron_' . $module_previous) . 'ms',
));
}
timer_start('cron_' . $module);
}
// Do not let an exception thrown by one module disturb another.
try {
module_invoke($module, 'cron');
@ -5553,6 +5576,20 @@ function drupal_cron_run() {
catch (Exception $e) {
watchdog_exception('cron', $e);
}
if ($time_logging_enabled) {
timer_stop('cron_' . $module);
$module_previous = $module;
}
}
if ($time_logging_enabled) {
if ($module_previous) {
watchdog('cron', 'Execution of @module_previous_cron() took @time.', array(
'@module_previous' => $module_previous,
'@time' => timer_read('cron_' . $module_previous) . 'ms',
));
}
}
// Record cron time.
@ -8212,7 +8249,10 @@ function entity_get_controller($entity_type) {
$controllers = &drupal_static(__FUNCTION__, array());
if (!isset($controllers[$entity_type])) {
$type_info = entity_get_info($entity_type);
$class = $type_info['controller class'];
// Explicitly fail for malformed entities missing a valid controller class.
if (!isset($type_info['controller class']) || !class_exists($class = $type_info['controller class'])) {
throw new EntityMalformedException(t('Missing or non-existent controller class on entity of type @entity_type.', array('@entity_type' => $entity_type)));
}
$controllers[$entity_type] = new $class($entity_type);
}
return $controllers[$entity_type];

View file

@ -63,6 +63,14 @@ class InsertQuery_mysql extends InsertQuery {
$max_placeholder = 0;
$values = array();
if (!is_array($this->insertValues)) {
if (version_compare(PHP_VERSION, '7.4', '>=')) {
throw new UnexpectedValueException();
}
else {
drupal_trigger_fatal_error('Unexpected Value');
}
}
if (count($this->insertValues)) {
foreach ($this->insertValues as $insert_values) {
$placeholders = array();
@ -96,6 +104,14 @@ class TruncateQuery_mysql extends TruncateQuery { }
class UpdateQuery_mysql extends UpdateQuery {
public function __toString() {
if (method_exists($this->connection, 'escapeField')) {
if (!is_array($this->fields)) {
if (version_compare(PHP_VERSION, '7.4', '>=')) {
throw new UnexpectedValueException();
}
else {
drupal_trigger_fatal_error('Unexpected Value');
}
}
$escapedFields = array();
foreach ($this->fields as $field => $data) {
$field = $this->connection->escapeField($field);

View file

@ -120,7 +120,15 @@ class InsertQuery_pgsql extends InsertQuery {
$max_placeholder = 0;
$values = array();
if (count($this->insertValues)) {
if (!is_array($this->insertValues)) {
if (version_compare(PHP_VERSION, '7.4', '>=')) {
throw new UnexpectedValueException();
}
else {
drupal_trigger_fatal_error('Unexpected Value');
}
}
if (count($this->insertValues)) {
foreach ($this->insertValues as $insert_values) {
$placeholders = array();

View file

@ -293,6 +293,15 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$class_name = $this->fetchOptions['class'];
}
if (count($this->fetchOptions['constructor_args'])) {
// Verify the current db connection to avoid this code being called
// in an inappropriate context.
$db_connection_options = Database::getConnection()->getConnectionOptions();
$defaults = array('sqlite', 'oracle');
$extras = variable_get('database_statement_prefetch_valid_db_drivers', array());
$valid_db_drivers = array_merge($defaults, $extras);
if (!in_array($db_connection_options['driver'], $valid_db_drivers)) {
throw new BadMethodCallException();
}
$reflector = new ReflectionClass($class_name);
$result = $reflector->newInstanceArgs($this->fetchOptions['constructor_args']);
}

View file

@ -1190,6 +1190,15 @@ class UpdateQuery extends Query implements QueryConditionInterface {
* The prepared statement.
*/
public function __toString() {
if (!is_array($this->expressionFields) || !is_array($this->fields)) {
if (version_compare(PHP_VERSION, '7.4', '>=')) {
throw new UnexpectedValueException();
}
else {
drupal_trigger_fatal_error('Unexpected Value');
}
}
// Create a sanitized comment string to prepend to the query.
$comments = $this->connection->makeComment($this->comments);

View file

@ -134,6 +134,9 @@ class DatabaseConnection_sqlite extends DatabaseConnection {
*/
public function __destruct() {
if ($this->tableDropped && !empty($this->attachedDatabases)) {
if (!is_array($this->attachedDatabases)) {
throw new UnexpectedValueException();
}
foreach ($this->attachedDatabases as $prefix) {
// Check if the database is now empty, ignore the internal SQLite tables.
try {

View file

@ -216,7 +216,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
if ($fatal) {
// When called from CLI, simply output a plain text message.
print html_entity_decode(strip_tags(t('%type: !message in %function (line %line of %file).', $error))). "\n";
exit;
exit(1);
}
}
@ -224,7 +224,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
if ($fatal) {
if (error_displayable($error)) {
// When called from JavaScript, simply output the error message.
print t('%type: !message in %function (line %line of %file).', $error);
print t('%type: !message in %function (line %line of %file).', _drupal_strip_error_file_path($error));
}
exit;
}
@ -242,7 +242,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
$class = 'status';
}
drupal_set_message(t('%type: !message in %function (line %line of %file).', $error), $class);
drupal_set_message(t('%type: !message in %function (line %line of %file).', _drupal_strip_error_file_path($error)), $class);
}
if ($fatal) {
@ -291,3 +291,28 @@ function _drupal_get_last_caller($backtrace) {
}
return $call;
}
/**
* Strip full path information from error details.
*
* @param $error
* An array with the following keys: %type, !message, %function, %file, %line
* and severity_level.
*
* @return
* An array with the same keys as the $error param but with full paths
* stripped from the %file element
*/
function _drupal_strip_error_file_path($error) {
if (!empty($error['%file'])) {
if (($drupal_root_position = strpos($error['%file'], DRUPAL_ROOT)) === 0) {
$root_length = strlen(DRUPAL_ROOT);
$error['%file'] = substr($error['%file'], $root_length + 1);
}
elseif ($drupal_root_position !== FALSE) {
// As a fallback, make sure DRUPAL_ROOT's value is not in the path.
$error['%file'] = str_replace(DRUPAL_ROOT, 'DRUPAL_ROOT', $error['%file']);
}
}
return $error;
}

View file

@ -2082,7 +2082,7 @@ function file_download() {
$target = implode('/', $args);
$uri = $scheme . '://' . $target;
$uri = file_uri_normalize_dot_segments($uri);
if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
if (file_stream_wrapper_valid_scheme($scheme) && is_file($uri)) {
$headers = file_download_headers($uri);
if (count($headers)) {
file_transfer($uri, $headers);

View file

@ -624,7 +624,7 @@ function drupal_mail_format_display_name($string) {
*/
function _drupal_wrap_mail_line(&$line, $key, $values) {
// Use soft-breaks only for purely quoted or unindented text.
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
// Break really long words at the maximum width allowed.
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n", TRUE);
}

View file

@ -478,6 +478,9 @@ function decode_entities($text) {
*/
function drupal_strlen($text) {
global $multibyte;
if (is_null($text)) {
return 0;
}
if ($multibyte == UNICODE_MULTIBYTE) {
return mb_strlen($text);
}

View file

@ -245,9 +245,6 @@ class Updater {
// Make sure the installation parent directory exists and is writable.
$this->prepareInstallDirectory($filetransfer, $args['install_dir']);
// Note: If the project is installed in sites/all, it will not be
// deleted. It will be installed in sites/default as that will override
// the sites/all reference and not break other sites which are using it.
if (is_dir($args['install_dir'] . '/' . $this->name)) {
// Remove the existing installed file.
$filetransfer->removeDirectory($args['install_dir'] . '/' . $this->name);

View file

@ -26,7 +26,7 @@ function drupal_var_export($var, $prefix = '') {
// Don't export keys if the array is non associative.
$export_keys = array_values($var) != $var;
foreach ($var as $key => $value) {
$output .= ' ' . ($export_keys ? drupal_var_export($key) . ' => ' : '') . drupal_var_export($value, ' ', FALSE) . ",\n";
$output .= ' ' . ($export_keys ? drupal_var_export($key) . ' => ' : '') . drupal_var_export($value, ' ') . ",\n";
}
$output .= ')';
}
@ -35,7 +35,6 @@ function drupal_var_export($var, $prefix = '') {
$output = $var ? 'TRUE' : 'FALSE';
}
elseif (is_string($var)) {
$line_safe_var = str_replace("\n", '\n', $var);
if (strpos($var, "\n") !== FALSE || strpos($var, "'") !== FALSE) {
// If the string contains a line break or a single quote, use the
// double quote export mode. Encode backslash and double quotes and