From fdc6dce421d74b0ce959795154d1677be5ecab8e Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 15 Dec 2024 23:23:54 +0000 Subject: [PATCH 1/2] ext/pdo_firebird: Throw ValueError if cursor name is too long --- ext/pdo_firebird/firebird_statement.c | 16 +++++++++--- .../tests/setCursorAttribute.phpt | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 ext/pdo_firebird/tests/setCursorAttribute.phpt diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index ceb10339a518c..910b325112c52 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -887,15 +887,25 @@ static int pdo_firebird_stmt_set_attribute(pdo_stmt_t *stmt, zend_long attr, zva default: return 0; case PDO_ATTR_CURSOR_NAME: - if (!try_convert_to_string(val)) { + zend_string *str_val = zval_try_get_string(val); + if (str_val == NULL) { + return 0; + } + // TODO Check cursor name does not have null bytes? + if (ZSTR_LEN(str_val) >= sizeof(S->name)) { + zend_value_error("Cursor name must not be longer than %zu bytes", sizeof(S->name) - 1); + zend_string_release(str_val); return 0; } - if (isc_dsql_set_cursor_name(S->H->isc_status, &S->stmt, Z_STRVAL_P(val),0)) { + if (isc_dsql_set_cursor_name(S->H->isc_status, &S->stmt, ZSTR_VAL(str_val), 0)) { php_firebird_error_stmt(stmt); + zend_string_release(str_val); return 0; } - strlcpy(S->name, Z_STRVAL_P(val), sizeof(S->name)); + /* Include trailing nul byte */ + memcpy(S->name, ZSTR_VAL(str_val), ZSTR_LEN(str_val) + 1); + zend_string_release(str_val); break; } return 1; diff --git a/ext/pdo_firebird/tests/setCursorAttribute.phpt b/ext/pdo_firebird/tests/setCursorAttribute.phpt new file mode 100644 index 0000000000000..c1c8e8673b7f8 --- /dev/null +++ b/ext/pdo_firebird/tests/setCursorAttribute.phpt @@ -0,0 +1,26 @@ +--TEST-- +Throw value error if cursor name is too long +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +query($query); + +try { + $stmt->setAttribute(PDO::ATTR_CURSOR_NAME, str_repeat('a', 35)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: Cursor name must not be longer than 31 bytes From 2655c32bd30ef2b4e521e53184717fef9039c794 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 16 Dec 2024 16:33:17 +0000 Subject: [PATCH 2/2] Update ext/pdo_firebird/tests/setCursorAttribute.phpt Co-authored-by: Saki Takamachi <34942839+SakiTakamachi@users.noreply.github.com> --- ext/pdo_firebird/tests/setCursorAttribute.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pdo_firebird/tests/setCursorAttribute.phpt b/ext/pdo_firebird/tests/setCursorAttribute.phpt index c1c8e8673b7f8..26fa55e91d21f 100644 --- a/ext/pdo_firebird/tests/setCursorAttribute.phpt +++ b/ext/pdo_firebird/tests/setCursorAttribute.phpt @@ -12,7 +12,7 @@ See https://github.com/FirebirdSQL/firebird/issues/7849 require 'testdb.inc'; $dbh = getDbConnection(); -$query = 'SELECT 1'; +$query = 'SELECT 1 FROM RDB$DATABASE'; $stmt = $dbh->query($query); try {