From 08d46845b40826eec6704316d4952de07b1d4f48 Mon Sep 17 00:00:00 2001
From: Juraj Nemec <jnemec@activit.sk>
Date: Wed, 20 Nov 2024 16:56:04 +0100
Subject: [PATCH 1/3] SA-CORE-2024-005 by cm0dit, greggles,
 GrandmaGlassesRopeMan, wim leers, mcdruid, ram4nd, fabianx, poker10

---
 modules/overlay/overlay-parent.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/overlay/overlay-parent.js b/modules/overlay/overlay-parent.js
index efb26370c50..0d41fadcc57 100644
--- a/modules/overlay/overlay-parent.js
+++ b/modules/overlay/overlay-parent.js
@@ -229,7 +229,7 @@ Drupal.overlay.destroy = function () {
  */
 Drupal.overlay.redirect = function (url) {
   // Create a native Link object, so we can use its object methods.
-  var link = $(url.link(url)).get(0);
+  var link = $("<a>").attr("href", url).get(0);
 
   // If the link is already open, force the hashchange event to simulate reload.
   if (window.location.href == link.href) {
@@ -865,7 +865,7 @@ Drupal.overlay.resetActiveClass = function(activePath) {
 Drupal.overlay.getPath = function (link, ignorePathFromQueryString) {
   if (typeof link == 'string') {
     // Create a native Link object, so we can use its object methods.
-    link = $(link.link(link)).get(0);
+    link = $("<a>").attr("href", link).get(0);
   }
 
   var path = link.pathname;

From cb5f7dee3d744a8c704848681e7f6859cf315d31 Mon Sep 17 00:00:00 2001
From: Juraj Nemec <jnemec@activit.sk>
Date: Wed, 20 Nov 2024 16:56:04 +0100
Subject: [PATCH 2/3] SA-CORE-2024-008 by mcdruid, fabianx, poker10, larowlan,
 longwave, alexpott

---
 includes/bootstrap.inc                |  3 +++
 includes/database/mysql/query.inc     | 16 ++++++++++++++++
 includes/database/pgsql/query.inc     | 10 +++++++++-
 includes/database/prefetch.inc        |  9 +++++++++
 includes/database/query.inc           |  9 +++++++++
 includes/database/sqlite/database.inc |  3 +++
 modules/system/system.install         |  7 +++++++
 modules/system/system.module          |  8 ++++++++
 8 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index a94164cc8ed..4ec8480b97a 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -457,6 +457,9 @@ abstract class DrupalCacheArray implements ArrayAccess {
     if ($this->bin == 'cache_form' && !variable_get('drupal_cache_array_persist_cache_form', FALSE)) {
       return;
     }
+    if (!is_array($this->keysToPersist)) {
+      throw new UnexpectedValueException();
+    }
     $data = array();
     foreach ($this->keysToPersist as $offset => $persist) {
       if ($persist) {
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index 3f0bcb7968a..525b895d2d1 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -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);
diff --git a/includes/database/pgsql/query.inc b/includes/database/pgsql/query.inc
index e2d587d5b74..5731e55944f 100644
--- a/includes/database/pgsql/query.inc
+++ b/includes/database/pgsql/query.inc
@@ -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();
 
diff --git a/includes/database/prefetch.inc b/includes/database/prefetch.inc
index 2a0bd55ce1e..d9952683ca8 100644
--- a/includes/database/prefetch.inc
+++ b/includes/database/prefetch.inc
@@ -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']);
           }
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 1c33ab4f80b..5a6642a51cb 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -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);
 
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index 2cf83ccb550..27a16f09b88 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -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 {
diff --git a/modules/system/system.install b/modules/system/system.install
index da493737754..acb95874518 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -3420,6 +3420,13 @@ function system_update_7087() {
   }
 }
 
+/**
+ * Clear caches as registry has been altered.
+ */
+function system_update_7088() {
+  // Empty update to clear caches.
+}
+
 /**
  * @} End of "defgroup updates-7.x-extra".
  * The next series of updates should start at 8000.
diff --git a/modules/system/system.module b/modules/system/system.module
index 9d7422f53cf..4986aa59040 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -4139,3 +4139,11 @@ function system_file_download($uri) {
     }
   }
 }
+
+/**
+ * Implements hook_registry_files_alter
+ */
+function system_registry_files_alter(&$files, $modules) {
+  // Database drivers that use DatabaseStatementPrefetch must include this file.
+  unset($files['includes/database/prefetch.inc']);
+}

From fa67320cf2109f1102201da5f66fd189c56f8b25 Mon Sep 17 00:00:00 2001
From: Juraj Nemec <jnemec@activit.sk>
Date: Wed, 20 Nov 2024 16:56:05 +0100
Subject: [PATCH 3/3] Drupal 7.102

---
 CHANGELOG.txt          | 6 ++++++
 includes/bootstrap.inc | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index d312a68dad9..4b7cea97f8f 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,9 @@
+Drupal 7.102, 2024-11-20
+------------------------
+- Fixed security issues:
+   - SA-CORE-2024-005
+   - SA-CORE-2024-008
+
 Drupal 7.101, 2024-06-05
 -----------------------
 - Various security improvements
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 4ec8480b97a..81c769a60d0 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -8,7 +8,7 @@
 /**
  * The current system version.
  */
-define('VERSION', '7.101');
+define('VERSION', '7.102');
 
 /**
  * Core API compatibility.