From 8a28a54e4d31a48a6f56a85c1c712919333eb4db Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 16 Jun 2026 16:23:28 -0400 Subject: [PATCH] Fix heap over-read seeding the long-column buffer in pdo_odbc In the long-column fetch path, when the ODBC driver reports the total column length rather than SQL_NO_TOTAL, the result string was seeded by copying orig_fetched_len + 1 bytes out of C->data, which holds at most LONG_COLUMN_BUFFER_SIZE bytes from the first SQLGetData. For a column larger than that buffer this reads past C->data. Seed only the bytes actually present in the buffer, matching the SQL_NO_TOTAL branch; the remainder is still fetched by the loop. --- ext/pdo_odbc/odbc_stmt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 940cf1209b14..bc87bdb14560 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -704,8 +704,9 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo } ssize_t to_fetch_byte = to_fetch_len + 1; char *buf2 = emalloc(to_fetch_byte); - zend_string *str = zend_string_init(C->data, to_fetch_byte, 0); - size_t used = to_fetch_len; + ssize_t seed_len = to_fetch_len > (LONG_COLUMN_BUFFER_SIZE - 1) ? (LONG_COLUMN_BUFFER_SIZE - 1) : to_fetch_len; + zend_string *str = zend_string_init(C->data, seed_len + 1, 0); + size_t used = seed_len; do { C->fetched_len = 0;