Skip to content

Commit c161bb0

Browse files
committed
Fix GH-18873 - Free column->descid appropriately (#18957)
fixes #18873 closes #18957
1 parent 69328ba commit c161bb0

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ PHP NEWS
2222
- MbString:
2323
. Fixed bug GH-18901 (integer overflow mb_split). (nielsdos)
2424

25+
- OCI8:
26+
. Fixed bug GH-18873 (OCI_RETURN_LOBS flag causes oci8 to leak memory).
27+
(Saki Takamachi)
28+
2529
- Opcache:
2630
. Fixed bug GH-18639 (Internal class aliases can break preloading + JIT).
2731
(nielsdos)

ext/oci8/oci8.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,12 +573,8 @@ void php_oci_column_hash_dtor(zval *data)
573573
zend_list_close(column->stmtid);
574574
}
575575

576-
if (column->descid) {
577-
if (GC_REFCOUNT(column->descid) == 1)
578-
zend_list_close(column->descid);
579-
else {
580-
GC_DELREF(column->descid);
581-
}
576+
if (column->descid && !GC_DELREF(column->descid)) {
577+
zend_list_free(column->descid);
582578
}
583579

584580
if (column->data) {

ext/oci8/tests/gh18873.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
GH-18873 (OCI_RETURN_LOBS flag causes oci8 to leak memory)
3+
--EXTENSIONS--
4+
oci8
5+
--SKIPIF--
6+
<?php
7+
require_once 'skipifconnectfailure.inc';
8+
if (getenv("USE_ZEND_ALLOC") === "0") die("skip requires ZendMM");
9+
?>
10+
--FILE--
11+
<?php
12+
require __DIR__.'/connect.inc';
13+
14+
$expectedStr = str_repeat('a', 1_001);
15+
$sql = 'select concat(TO_CLOB(\'' . str_repeat('a', 1_000) . '\'), TO_CLOB(\'a\')) AS "v" from "DUAL"';
16+
17+
$memUsages = array_flip(range(0, 100 - 1));
18+
foreach (array_keys($memUsages) as $k) {
19+
$stid = oci_parse($c, $sql);
20+
oci_execute($stid);
21+
$row = oci_fetch_array($stid, \OCI_ASSOC | \OCI_RETURN_LOBS);
22+
$res = $row['v'];
23+
24+
$memUsages[$k] = memory_get_usage();
25+
}
26+
27+
$memUsages = array_slice($memUsages, 1, null, true);
28+
$memUsages = array_unique($memUsages);
29+
30+
if (count($memUsages) !== 1) {
31+
var_dump($memUsages);
32+
throw new \Exception('memory leak detected');
33+
}
34+
35+
echo "Done!\n";
36+
?>
37+
--EXPECT--
38+
Done!

0 commit comments

Comments
 (0)