1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix GH-16450: PDO_ODBC can inject garbage into field values

A previous bug fix[1] relied on ODBC drivers to properly count down the
`StrLen_or_IndPtr` argument for consecutive calls to `SQLGetData()`.
Apparently, not all drivers handle this correctly, so we cannot assert
they do.  Instead we fall back to the old behavior for drivers which
would violate the assertion.

A test against SQLServer (which we currently use in CI) would not make
sense, since the respective drivers do not exhibit that behavior.
Instead we target the regression test especially to a MS Access
database.

Since there is apparently no way to easily create an MS Access database
programmatically, we commit a minimal empty DB which is used for the
regression test, and could also be used by other test cases.

[1] <bccca0b53aa60a62e2988c750fc73c02d109e642>

Closes GH-16587.
This commit is contained in:
Christoph M. Becker
2024-10-25 14:36:38 +02:00
parent e5d63eb4b9
commit c9eafc1954
4 changed files with 42 additions and 3 deletions

3
NEWS
View File

@@ -79,6 +79,9 @@ PHP NEWS
. Fixed bug GH-16433 (Large values for openssl_csr_sign() $days overflow).
(cmb)
- PDO_ODBC:
. Fixed bug GH-16450 (PDO_ODBC can inject garbage into field values). (cmb)
- Phar:
. Fixed bug GH-16406 (Assertion failure in ext/phar/phar.c:2808). (nielsdos)

View File

@@ -689,11 +689,12 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo
/* read block. 256 bytes => 255 bytes are actually read, the last 1 is NULL */
rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, buf2, 256, &C->fetched_len);
/* adjust `used` in case we have length info from the driver */
/* adjust `used` in case we have proper length info from the driver */
if (orig_fetched_len >= 0 && C->fetched_len >= 0) {
SQLLEN fixed_used = orig_fetched_len - C->fetched_len;
ZEND_ASSERT(fixed_used <= used + 1);
used = fixed_used;
if (fixed_used <= used + 1) {
used = fixed_used;
}
}
/* resize output buffer and reassemble block */

View File

@@ -0,0 +1,35 @@
--TEST--
GH-16450 (PDO_ODBC can inject garbage into field values)
--EXTENSIONS--
pdo_odbc
--SKIPIF--
<?php
$dbpath = __DIR__ . "/test.mdb";
try {
new PDO("odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$dbpath;Uid=Admin;Pwd=;");
} catch (PDOException $ex) {
die("skip Cannot connect to MS Access database");
}
?>
--FILE--
<?php
$dbpath = __DIR__ . "/test.mdb";
$pdo = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$dbpath;Uid=Admin;Pwd=;");
$pdo->exec("CREATE TABLE gh16450 (Id INT, MyLongText LONGCHAR)");
$pdo->exec(sprintf("INSERT INTO gh16450 VALUES (1, '%s')", str_repeat("_", 2048)));
$pdo->exec(sprintf("INSERT INTO gh16450 VALUES (1, '%s')", str_repeat("_", 2049)));
$stmt = $pdo->query("SELECT MyLongText FROM gh16450");
var_dump($stmt->fetchColumn(0));
var_dump($stmt->fetchColumn(0));
?>
--CLEAN--
<?php
$dbpath = __DIR__ . "/test.mdb";
$pdo = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$dbpath;Uid=Admin;Pwd=;");
$pdo->exec("DROP TABLE gh16450");
?>
--EXPECT--
string(2048) "________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________"
string(2049) "_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________"

BIN
ext/pdo_odbc/tests/test.mdb Normal file

Binary file not shown.