[php-src] master: Merge branch '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:57-04:00

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

Merge branch 'PHP-8.5'

* PHP-8.5:
  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 367860feb471..6b1e857a8708 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,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)
 
 - Reflection:
   . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes).
diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c
index e499c2fd45b9..dbdb0066578b 100644
--- a/ext/pdo_odbc/odbc_driver.c
+++ b/ext/pdo_odbc/odbc_driver.c
@@ -93,6 +93,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.