[php-src] master: Merge branch 'PHP-8.4' into PHP-8.5

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-07-14T16:20:13-04:00

Commit: https://github.com/php/php-src/commit/c9f28005e8d8972aae7c1870b61e782978dbf6af
Raw diff: https://github.com/php/php-src/commit/c9f28005e8d8972aae7c1870b61e782978dbf6af.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  Fix GH-22665: pdo_odbc OOB write on oversized diagnostic length

Changed paths:
  A  ext/pdo_odbc/tests/gh22665.phpt
  M  NEWS
  M  ext/pdo_odbc/odbc_driver.c


Diff:

diff --git a/NEWS b/NEWS
index a954be2e35c2..7e138fcc2bb1 100644
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,8 @@ PHP                                                                        NEWS
     driver-reported display size). (iliaal)
   . Fixed bug GH-22666 (Heap buffer overflow when an output parameter value is
     longer than the declared maxlen). (iliaal)
+  . Fixed bug GH-22665 (Out-of-bounds write when the ODBC driver reports a
+    diagnostic message length beyond the error buffer). (iliaal)
 
 - Phar:
   . Fixed inconsistent handling of the magic ".phar" directory. Paths such as
diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c
index 0367207e89bb..c07718f1dc45 100644
--- a/ext/pdo_odbc/odbc_driver.c
+++ b/ext/pdo_odbc/odbc_driver.c
@@ -95,6 +95,8 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement,
 
 	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
 		errmsgsize = 0;
+	} else if ((size_t) errmsgsize >= sizeof(einfo->last_err_msg)) {
+		errmsgsize = sizeof(einfo->last_err_msg) - 1;
 	}
 
 	einfo->last_err_msg[errmsgsize] = '\0';
diff --git a/ext/pdo_odbc/tests/gh22665.phpt b/ext/pdo_odbc/tests/gh22665.phpt
new file mode 100644
index 000000000000..d6edc62288e8
--- /dev/null
+++ b/ext/pdo_odbc/tests/gh22665.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-22665 (OOB write in pdo_odbc_error when the driver reports a long message)
+--EXTENSIONS--
+pdo_odbc
+--SKIPIF--
+<?php
+require __DIR__ . '/config.inc';
+try {
+    $pdo = new PDO(PDO_ODBC_SQLITE_DSN);
+} catch (PDOException $e) {
+    die("skip requires the SQLite3 ODBC driver");
+}
+?>
+--FILE--
+<?php
+require __DIR__ . '/config.inc';
+$pdo = new PDO(PDO_ODBC_SQLITE_DSN, null, null, [
+    PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,
+]);
+
+// A failing query with a long identifier makes the driver report a diagnostic
+// message length >= the fixed last_err_msg buffer. The terminator write must
+// stay inside the buffer.
+$pdo->query('SELECT * FROM "' . str_repeat('A', 4096) . '"');
+$info = $pdo->errorInfo();
+
+echo "sqlstate: ", $info[0], "\n";
+echo "done\n";
+?>
+--EXPECT--
+sqlstate: HY000
+done
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.