Skip to content

Commit 9d4f8b5

Browse files
committed
Fixed GH-18276 - persistent connection - "zend_mm_heap corrupted" with setAttribute() (#18280)
Closes #18280 Fixes #18276
1 parent 701f3a1 commit 9d4f8b5

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ PHP NEWS
2727
(nielsdos)
2828
. Fix potential leaks when writing to BIO fails. (nielsdos)
2929

30+
- PDO Firebird:
31+
. Fixed GH-18276 - persistent connection - "zend_mm_heap corrupted"
32+
with setAttribute() (SakiTakamachi).
33+
3034
- SPL:
3135
. Fixed bug GH-18322 (SplObjectStorage debug handler mismanages memory).
3236
(nielsdos)

ext/pdo_firebird/firebird_driver.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -492,13 +492,13 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */
492492
}
493493

494494
if (H->date_format) {
495-
efree(H->date_format);
495+
pefree(H->date_format, dbh->is_persistent);
496496
}
497497
if (H->time_format) {
498-
efree(H->time_format);
498+
pefree(H->time_format, dbh->is_persistent);
499499
}
500500
if (H->timestamp_format) {
501-
efree(H->timestamp_format);
501+
pefree(H->timestamp_format, dbh->is_persistent);
502502
}
503503

504504
pefree(H, dbh->is_persistent);
@@ -881,9 +881,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
881881
return false;
882882
}
883883
if (H->date_format) {
884-
efree(H->date_format);
884+
pefree(H->date_format, dbh->is_persistent);
885+
H->date_format = NULL;
885886
}
886-
spprintf(&H->date_format, 0, "%s", ZSTR_VAL(str));
887+
H->date_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent);
887888
zend_string_release_ex(str, 0);
888889
}
889890
return true;
@@ -895,9 +896,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
895896
return false;
896897
}
897898
if (H->time_format) {
898-
efree(H->time_format);
899+
pefree(H->time_format, dbh->is_persistent);
900+
H->time_format = NULL;
899901
}
900-
spprintf(&H->time_format, 0, "%s", ZSTR_VAL(str));
902+
H->time_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent);
901903
zend_string_release_ex(str, 0);
902904
}
903905
return true;
@@ -909,9 +911,10 @@ static bool firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *
909911
return false;
910912
}
911913
if (H->timestamp_format) {
912-
efree(H->timestamp_format);
914+
pefree(H->timestamp_format, dbh->is_persistent);
915+
H->timestamp_format = NULL;
913916
}
914-
spprintf(&H->timestamp_format, 0, "%s", ZSTR_VAL(str));
917+
H->timestamp_format = pestrndup(ZSTR_VAL(str), ZSTR_LEN(str),dbh->is_persistent);
915918
zend_string_release_ex(str, 0);
916919
}
917920
return true;

ext/pdo_firebird/tests/gh18276.phpt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GH-18276 (persistent connection - setAttribute(Pdo\Firebird::ATTR_DATE_FORMAT, ..) results in "zend_mm_heap corrupted")
3+
--EXTENSIONS--
4+
pdo_firebird
5+
--SKIPIF--
6+
<?php require('skipif.inc'); ?>
7+
--XLEAK--
8+
A bug in firebird causes a memory leak when calling `isc_attach_database()`.
9+
See https://github.com/FirebirdSQL/firebird/issues/7849
10+
--FILE--
11+
<?php
12+
13+
require("testdb.inc");
14+
unset($dbh);
15+
16+
for ($i = 0; $i < 2; $i++) {
17+
$dbh = new PDO(
18+
PDO_FIREBIRD_TEST_DSN,
19+
PDO_FIREBIRD_TEST_USER,
20+
PDO_FIREBIRD_TEST_PASS,
21+
[
22+
PDO::ATTR_PERSISTENT => true,
23+
],
24+
);
25+
// Avoid interned
26+
$dbh->setAttribute(PDO::FB_ATTR_DATE_FORMAT, str_repeat('Y----m----d', random_int(1, 1)));
27+
$dbh->setAttribute(PDO::FB_ATTR_TIME_FORMAT, str_repeat('H::::i::::s', random_int(1, 1)));
28+
$dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', random_int(1, 1)));
29+
unset($dbh);
30+
}
31+
32+
echo 'done!';
33+
?>
34+
--EXPECT--
35+
done!

0 commit comments

Comments
 (0)