From 9d4f8b5379f2dfb071f4311ed5d0c421e014dbf7 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 8 Apr 2025 23:32:36 +0900 Subject: [PATCH] Fixed GH-18276 - persistent connection - "zend_mm_heap corrupted" with setAttribute() (#18280) Closes #18280 Fixes #18276 --- NEWS | 4 ++++ ext/pdo_firebird/firebird_driver.c | 21 +++++++++-------- ext/pdo_firebird/tests/gh18276.phpt | 35 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 ext/pdo_firebird/tests/gh18276.phpt diff --git a/NEWS b/NEWS index 6e5a4bc4cfc..7d660e26cef 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,10 @@ PHP NEWS (nielsdos) . Fix potential leaks when writing to BIO fails. (nielsdos) +- PDO Firebird: + . Fixed GH-18276 - persistent connection - "zend_mm_heap corrupted" + with setAttribute() (SakiTakamachi). + - SPL: . Fixed bug GH-18322 (SplObjectStorage debug handler mismanages memory). (nielsdos) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 4f8cd83d7b8..504e739a974 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -492,13 +492,13 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ } if (H->date_format) { - efree(H->date_format); + pefree(H->date_format, dbh->is_persistent); } if (H->time_format) { - efree(H->time_format); + pefree(H->time_format, dbh->is_persistent); } if (H->timestamp_format) { - efree(H->timestamp_format); + pefree(H->timestamp_format, dbh->is_persistent); } pefree(H, dbh->is_persistent); @@ -881,9 +881,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * return false; } if (H->date_format) { - efree(H->date_format); + pefree(H->date_format, dbh->is_persistent); + H->date_format = NULL; } - spprintf(&H->date_format, 0, "%s", ZSTR_VAL(str)); + H->date_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -895,9 +896,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * return false; } if (H->time_format) { - efree(H->time_format); + pefree(H->time_format, dbh->is_persistent); + H->time_format = NULL; } - spprintf(&H->time_format, 0, "%s", ZSTR_VAL(str)); + H->time_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -909,9 +911,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * return false; } if (H->timestamp_format) { - efree(H->timestamp_format); + pefree(H->timestamp_format, dbh->is_persistent); + H->timestamp_format = NULL; } - spprintf(&H->timestamp_format, 0, "%s", ZSTR_VAL(str)); + H->timestamp_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent); zend_string_release_ex(str, 0); } return true; diff --git a/ext/pdo_firebird/tests/gh18276.phpt b/ext/pdo_firebird/tests/gh18276.phpt new file mode 100644 index 00000000000..610876166cc --- /dev/null +++ b/ext/pdo_firebird/tests/gh18276.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-18276 (persistent connection - setAttribute(Pdo\Firebird::ATTR_DATE_FORMAT, ..) results in "zend_mm_heap corrupted") +--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-- + true, + ], + ); + // Avoid interned + $dbh->setAttribute(PDO::FB_ATTR_DATE_FORMAT, str_repeat('Y----m----d', random_int(1, 1))); + $dbh->setAttribute(PDO::FB_ATTR_TIME_FORMAT, str_repeat('H::::i::::s', random_int(1, 1))); + $dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', random_int(1, 1))); + unset($dbh); +} + +echo 'done!'; +?> +--EXPECT-- +done!