Skip to content

Commit 8c22556

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: ext/pdo: Release driver options after bindParam and bindColumn
2 parents 9db3f18 + 22237f2 commit 8c22556

3 files changed

Lines changed: 41 additions & 4 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ PHP NEWS
105105
whose constructor arguments it rejects. (Ilia Alshanetsky)
106106
. Fixed PDO::ATTR_STATEMENT_CLASS constructor_args type errors reporting
107107
"array given" regardless of the value passed. (Ilia Alshanetsky)
108+
. Fixed PDOStatement::bindParam() and bindColumn() leaking the driver
109+
options value. (Ilia Alshanetsky)
108110

109111
- PDO_Firebird:
110112
. Fixed bug GH-23758 (PDO_Firebird returns null for non-null empty BLOBs).

‎ext/pdo/pdo_stmt.c‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,6 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_
283283
param->stmt = stmt;
284284
param->is_param = is_param;
285285

286-
if (Z_REFCOUNTED(param->driver_params)) {
287-
Z_ADDREF(param->driver_params);
288-
}
289-
290286
if (!is_param && param->name && stmt->columns) {
291287
/* try to map the name to the column */
292288
int i;
@@ -370,6 +366,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_
370366
} else {
371367
zend_hash_index_del(hash, pparam->paramno);
372368
}
369+
ZVAL_UNDEF(&param->driver_params);
373370
/* param->parameter is freed by hash dtor */
374371
ZVAL_UNDEF(&param->parameter);
375372
return 0;
@@ -1350,6 +1347,9 @@ static void register_bound_param(INTERNAL_FUNCTION_PARAMETERS, int is_param) /*
13501347
if (!Z_ISUNDEF(param.parameter)) {
13511348
zval_ptr_dtor(&(param.parameter));
13521349
}
1350+
if (!Z_ISUNDEF(param.driver_params)) {
1351+
zval_ptr_dtor(&param.driver_params);
1352+
}
13531353

13541354
RETURN_FALSE;
13551355
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
PDO SQLite releases driverOptions objects after binding or failed registration
3+
--EXTENSIONS--
4+
pdo_sqlite
5+
--FILE--
6+
<?php
7+
class Tracked {}
8+
9+
$db = new PDO('sqlite::memory:');
10+
11+
$stmt = $db->prepare('SELECT ? AS value');
12+
$value = 1;
13+
$driverOptions = [new Tracked()];
14+
$weakReference = WeakReference::create($driverOptions[0]);
15+
var_dump($stmt->bindParam(1, $value, PDO::PARAM_STR, 0, $driverOptions));
16+
unset($driverOptions, $value, $stmt);
17+
gc_collect_cycles();
18+
var_dump($weakReference->get());
19+
20+
$stmt = $db->prepare('SELECT ? AS value');
21+
$stmt->execute();
22+
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
23+
$value = null;
24+
$driverOptions = [new Tracked()];
25+
$weakReference = WeakReference::create($driverOptions[0]);
26+
var_dump(@$stmt->bindColumn('missing', $value, PDO::PARAM_STR, 0, $driverOptions));
27+
unset($driverOptions);
28+
var_dump($weakReference->get());
29+
unset($value, $stmt);
30+
?>
31+
--EXPECT--
32+
bool(true)
33+
NULL
34+
bool(false)
35+
NULL

0 commit comments

Comments
 (0)