Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Drupal 7.101. For more information, see https://www.drupal.org/project/drupal/releases/7.101 #203

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,35 @@
################

################
# Includes
# Workflow
#
# Additional configuration can be provided through includes.
# One advantage of include files is that if they are updated upstream, the
# changes affect all pipelines using that include.
# Define conditions for when the pipeline will run.
# For example:
# * On commit
# * On merge request
# * On manual trigger
# * etc.
# https://docs.gitlab.com/ee/ci/jobs/job_control.html#specify-when-jobs-run-with-rules
#
# Includes can be overriden by re-declaring anything provided in an include,
# here in gitlab-ci.yml
# https://docs.gitlab.com/ee/ci/yaml/includes.html#override-included-configuration-values
# Pipelines can also be configured to run on a schedule,though they still must meet the conditions defined in Workflow and Rules. This can be used, for example, to do nightly regression testing:
# https://gitlab.com/help/ci/pipelines/schedules
################

include:
- project: $_GITLAB_TEMPLATES_REPO
ref: $_GITLAB_TEMPLATES_REF
file:
- '/includes/include.drupalci.variables.yml'
- '/includes/include.drupalci.workflows.yml'
workflow:
rules:
# These 3 rules from https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml
# Run on merge requests
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
# Run when called from an upstream pipeline https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html?tab=Multi-project+pipeline#use-rules-to-control-downstream-pipeline-jobs
- if: $CI_PIPELINE_SOURCE == 'pipeline'
# Run on commits.
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project"
# The last rule above blocks manual and scheduled pipelines on non-default branch. The rule below allows them:
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project"
# Run if triggered from Web using 'Run Pipelines'
- if: $CI_PIPELINE_SOURCE == "web"
# Run if triggered from WebIDE
- if: $CI_PIPELINE_SOURCE == "webide"

################
# Variables
Expand All @@ -42,9 +54,11 @@ include:
################

variables:
_CONFIG_DOCKERHUB_ROOT: "drupalci"
_TARGET_PHP: "8.1"
CONCURRENCY: 15
GIT_DEPTH: "3"
COMPOSER_ALLOW_SUPERUSER: 1

################
# Stages
Expand Down
7 changes: 7 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ DirectoryIndex index.php index.html index.htm

# Various header fixes.
<IfModule mod_headers.c>
# Disable content sniffing for all responses, since it's an attack vector.
# This header is also set in drupal_deliver_html_page(), which depending on
# Apache configuration might get placed in the 'onsuccess' table. To prevent
# header duplication, unset that one prior to setting in the 'always' table.
# See "To circumvent this limitation..." in
# https://httpd.apache.org/docs/current/mod/mod_headers.html.
Header onsuccess unset X-Content-Type-Options
# Disable content sniffing, since it's an attack vector.
Header always set X-Content-Type-Options nosniff
# Disable Proxy header, since it's an attack vector.
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Drupal 7.101, 2024-06-05
-----------------------
- Various security improvements
- Various bug fixes, optimizations and improvements

Drupal 7.100, 2024-03-06
------------------------
- Security improvements
Expand Down
2 changes: 1 addition & 1 deletion includes/ajax.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions includes/bootstrap.inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* The current system version.
*/
define('VERSION', '7.100');
define('VERSION', '7.101');

/**
* Core API compatibility.
Expand Down Expand Up @@ -2310,7 +2310,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));
Expand Down
38 changes: 37 additions & 1 deletion includes/common.inc
Original file line number Diff line number Diff line change
Expand Up @@ -5561,15 +5561,48 @@ 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');
}
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.
Expand Down Expand Up @@ -8229,7 +8262,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];
Expand Down
2 changes: 1 addition & 1 deletion includes/errors.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
2 changes: 1 addition & 1 deletion includes/file.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2086,7 +2086,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);
Expand Down
3 changes: 3 additions & 0 deletions includes/unicode.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
3 changes: 0 additions & 3 deletions includes/updater.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 22 additions & 4 deletions modules/dblog/dblog.test
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,30 @@ class DBLogTestCase extends DrupalWebTestCase {
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
$this->assertTrue($count > $row_limit, format_string('Dblog row count of @count exceeds row limit of @limit', array('@count' => $count, '@limit' => $row_limit)));

// Get last ID to compare against; log entries get deleted, so we can't
// reliably add the number of newly created log entries to the current count
// to measure number of log entries created by cron.
$last_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();

// Run a cron job.
$this->cronRun();
// Verify that the database log row count equals the row limit plus one
// because cron adds a record after it runs.
$count = db_query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
$this->assertTrue($count == $row_limit + 1, format_string('Dblog row count of @count equals row limit of @limit plus one', array('@count' => $count, '@limit' => $row_limit)));

// Get last ID after cron was run.
$current_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();

// Only one final "cron is finished" message should be logged.
$this->assertEqual($current_id - $last_id, 1, format_string('Cron added @count of @expected new log entries', array('@count' => $current_id - $last_id, '@expected' => 1)));

// Test enabling of detailed cron logging.
// Get the number of enabled modules. Cron adds a log entry for each module.
$module_count = count(module_implements('cron'));
variable_set('cron_detailed_logging', 1);
$last_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
$this->cronRun();
$current_id = db_query('SELECT MAX(wid) FROM {watchdog}')->fetchField();

// The number of log entries created.
$this->assertEqual($current_id - $last_id, $module_count + 2, format_string('Cron added @count of @expected new log entries', array('@count' => $current_id - $last_id, '@expected' => $module_count + 2)));
}

/**
Expand Down
7 changes: 1 addition & 6 deletions modules/node/node.admin.inc
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,7 @@ function node_filter_form() {
);
foreach ($session as $filter) {
list($type, $value) = $filter;
if ($type == 'term') {
// Load term name from DB rather than search and parse options array.
$value = module_invoke('taxonomy', 'term_load', $value);
$value = $value->name;
}
elseif ($type == 'language') {
if ($type == 'language') {
$value = $value == LANGUAGE_NONE ? t('Language neutral') : module_invoke('locale', 'language_name', $value);
}
else {
Expand Down
25 changes: 12 additions & 13 deletions modules/simpletest/drupal_web_test_case.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,23 +560,22 @@ public function run(array $methods = array()) {
'function' => $class . '->' . $method . '()',
);
$completion_check_id = DrupalTestCase::insertAssert($this->testId, $class, FALSE, t('The test did not complete due to a fatal error.'), 'Completion check', $caller);
$this->setUp();
if ($this->setup) {
try {
try {
$this->setUp();
if ($this->setup) {
$this->$method();
// Finish up.
$this->tearDown();
}
catch (Throwable $e) {
$this->exceptionHandler($e);
}
catch (Exception $e) {
// Cater for older PHP versions.
$this->exceptionHandler($e);
else {
$this->fail(t("The test cannot be executed because it has not been set up properly."));
}
$this->tearDown();
}
else {
$this->fail(t("The test cannot be executed because it has not been set up properly."));
catch (Throwable $e) {
$this->exceptionHandler($e);
}
catch (Exception $e) {
// Cater for older PHP versions.
$this->exceptionHandler($e);
}
// Remove the completion check record.
DrupalTestCase::deleteAssert($completion_check_id);
Expand Down
12 changes: 12 additions & 0 deletions modules/simpletest/tests/ajax.test
Original file line number Diff line number Diff line change
Expand Up @@ -618,4 +618,16 @@ class AJAXElementValidation extends AJAXTestCase {
$this->assertNoText(t('Error message'), "No error message in resultant JSON");
$this->assertText('ajax_forms_test_validation_form_callback invoked', 'The correct callback was invoked');
}

/**
* Try to open default Ajax callback without passing required data.
*/
function testAJAXPathWithoutData() {
$this->drupalGet('system/ajax');
$query_parameters = array(
':type' => 'php',
':severity' => WATCHDOG_WARNING,
);
$this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND severity = :severity', $query_parameters)->fetchField(), 0, 'No warning message appears in the logs.');
}
}
29 changes: 29 additions & 0 deletions modules/simpletest/tests/entity_crud.test
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,33 @@ class EntityLoadTestCase extends DrupalWebTestCase {
$nodes_loaded = entity_load('node', array('1.', '2'));
$this->assertEqual(count($nodes_loaded), 1);
}

/**
* Tests the controller class loading functionality on non-existing entity
* types and on entities without valid controller class.
*/
public function testEntityLoadInvalidControllerClass() {
// Ensure that loading a non-existing entity type will throw an
// EntityMalformedException.
try {
entity_load('test', array('1'));
$this->fail(t('Cannot load a controller class on non-existing entity type.'));
}
catch (EntityMalformedException $e) {
$this->pass(t('Cannot load a controller class on non-existing entity type.'));
}

// Ensure that loading an entity without valid controller class will throw
// an EntityMalformedException.
module_enable(array('entity_crud_hook_test'));
variable_set('entity_crud_hook_test_alter_controller_class', TRUE);
try {
entity_load('node', array('1'));
$this->fail(t('Cannot load a missing or non-existent controller class.'));
}
catch (EntityMalformedException $e) {
$this->pass(t('Cannot load a missing or non-existent controller class.'));
}
variable_set('entity_crud_hook_test_alter_controller_class', FALSE);
}
}
10 changes: 10 additions & 0 deletions modules/simpletest/tests/entity_crud_hook_test.module
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,13 @@ function entity_crud_hook_test_taxonomy_vocabulary_delete() {
function entity_crud_hook_test_user_delete() {
$_SESSION['entity_crud_hook_test'][] = (__FUNCTION__ . ' called');
}

/**
* Implements hook_entity_info_alter().
*/
function entity_crud_hook_test_entity_info_alter(&$entity_info) {
if (variable_get('entity_crud_hook_test_alter_controller_class', FALSE)) {
// Set the controller class for nodes to NULL.
$entity_info['node']['controller class'] = NULL;
}
}
Loading
Loading