From 1c259193acf8f40d2748dc5ddacf215ade3f24b4 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 8 Apr 2025 23:32:36 +0900 Subject: [PATCH 1/4] Added a test --- ext/pdo_firebird/tests/gh18276.phpt | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 ext/pdo_firebird/tests/gh18276.phpt diff --git a/ext/pdo_firebird/tests/gh18276.phpt b/ext/pdo_firebird/tests/gh18276.phpt new file mode 100644 index 0000000000000..c58fb526e38e2 --- /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', 1)); + $dbh->setAttribute(PDO::FB_ATTR_TIME_FORMAT, str_repeat('H::::i::::s', 1)); + $dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', 1)); + unset($dbh); +} + +echo 'done!'; +?> +--EXPECT-- +done! From 3bf28c7bd38b050efc48a414226cb5194f4a34a8 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Tue, 8 Apr 2025 23:35:14 +0900 Subject: [PATCH 2/4] When freeing memory, set the pointer to NULL. --- ext/pdo_firebird/firebird_driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 4f8cd83d7b8ab..33da49be58c33 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -493,12 +493,15 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ if (H->date_format) { efree(H->date_format); + H->date_format = NULL; } if (H->time_format) { efree(H->time_format); + H->time_format = NULL; } if (H->timestamp_format) { efree(H->timestamp_format); + H->timestamp_format = NULL; } pefree(H, dbh->is_persistent); @@ -882,6 +885,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * } if (H->date_format) { efree(H->date_format); + H->date_format = NULL; } spprintf(&H->date_format, 0, "%s", ZSTR_VAL(str)); zend_string_release_ex(str, 0); @@ -896,6 +900,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * } if (H->time_format) { efree(H->time_format); + H->time_format = NULL; } spprintf(&H->time_format, 0, "%s", ZSTR_VAL(str)); zend_string_release_ex(str, 0); @@ -910,6 +915,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * } if (H->timestamp_format) { efree(H->timestamp_format); + H->timestamp_format = NULL; } spprintf(&H->timestamp_format, 0, "%s", ZSTR_VAL(str)); zend_string_release_ex(str, 0); From 8d15cdb2c0f42160675f66e4f47f1916d43336dc Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Wed, 9 Apr 2025 09:48:05 +0900 Subject: [PATCH 3/4] Allocate and free memory properly --- ext/pdo_firebird/firebird_driver.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 33da49be58c33..d2789d2d5afa1 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -492,15 +492,15 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ } if (H->date_format) { - efree(H->date_format); + pefree(H->date_format, dbh->is_persistent); H->date_format = NULL; } if (H->time_format) { - efree(H->time_format); + pefree(H->time_format, dbh->is_persistent); H->time_format = NULL; } if (H->timestamp_format) { - efree(H->timestamp_format); + pefree(H->timestamp_format, dbh->is_persistent); H->timestamp_format = NULL; } @@ -884,10 +884,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 = pestrdup(ZSTR_VAL(str), dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -899,10 +899,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 = pestrdup(ZSTR_VAL(str), dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -914,10 +914,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 = pestrdup(ZSTR_VAL(str), dbh->is_persistent); zend_string_release_ex(str, 0); } return true; From af6528e94703330c822122b5f497285d55c481a2 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Thu, 10 Apr 2025 09:03:28 +0900 Subject: [PATCH 4/4] address comments --- ext/pdo_firebird/firebird_driver.c | 9 +++------ ext/pdo_firebird/tests/gh18276.phpt | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index d2789d2d5afa1..504e739a974d9 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -493,15 +493,12 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ if (H->date_format) { pefree(H->date_format, dbh->is_persistent); - H->date_format = NULL; } if (H->time_format) { pefree(H->time_format, dbh->is_persistent); - H->time_format = NULL; } if (H->timestamp_format) { pefree(H->timestamp_format, dbh->is_persistent); - H->timestamp_format = NULL; } pefree(H, dbh->is_persistent); @@ -887,7 +884,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * pefree(H->date_format, dbh->is_persistent); H->date_format = NULL; } - H->date_format = pestrdup(ZSTR_VAL(str), dbh->is_persistent); + H->date_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -902,7 +899,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * pefree(H->time_format, dbh->is_persistent); H->time_format = NULL; } - H->time_format = pestrdup(ZSTR_VAL(str), dbh->is_persistent); + H->time_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent); zend_string_release_ex(str, 0); } return true; @@ -917,7 +914,7 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval * pefree(H->timestamp_format, dbh->is_persistent); H->timestamp_format = NULL; } - H->timestamp_format = pestrdup(ZSTR_VAL(str), dbh->is_persistent); + 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 index c58fb526e38e2..610876166ccf7 100644 --- a/ext/pdo_firebird/tests/gh18276.phpt +++ b/ext/pdo_firebird/tests/gh18276.phpt @@ -23,9 +23,9 @@ for ($i = 0; $i < 2; $i++) { ], ); // Avoid interned - $dbh->setAttribute(PDO::FB_ATTR_DATE_FORMAT, str_repeat('Y----m----d', 1)); - $dbh->setAttribute(PDO::FB_ATTR_TIME_FORMAT, str_repeat('H::::i::::s', 1)); - $dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', 1)); + $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); }