From 9d20289180b19c6ded6d287dc207d2d73c70e150 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 21 Jun 2026 08:07:22 -0400 Subject: [PATCH] Fix signed dbconvert() return stored into size_t in dblib lastInsertId dblib_handle_last_id() stored the DBINT return of dbconvert() into a size_t len. dbconvert() returns -1 on conversion failure, which sign-extends to SIZE_MAX and is passed as the length to zend_string_init(), reading far past the 40-byte buffer and requesting a SIZE_MAX allocation. Hold the result in a DBINT and bail on a negative return, matching the failure-returns-NULL handling already used for dbresults()/dbnextrow()/dbdatlen() earlier in the function. --- ext/pdo_dblib/dblib_driver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index d1d849168bab..f81e9e7397f3 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -234,7 +234,7 @@ zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name) RETCODE ret; char *id = NULL; - size_t len; + DBINT len; zend_string *ret_id; /* @@ -271,6 +271,11 @@ zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name) len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)40); dbcancel(H->link); + if (len < 0) { + efree(id); + return NULL; + } + ret_id = zend_string_init(id, len, 0); efree(id); return ret_id;