Skip to content

Commit 2330863

Browse files
committed
ext/session: fix missing zval_ptr_dtor for retval in PS_GC_FUNC(user)
PS_GC_FUNC(user) did not call zval_ptr_dtor() on the return value of the user GC callback, leaking memory when the callback returned a reference-counted value. All other user handlers (write, destroy, validate_sid, update_timestamp) already free retval correctly.
1 parent 6c5bed3 commit 2330863

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

ext/session/mod_user.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ PS_GC_FUNC(user)
218218
/* Anything else is some kind of error */
219219
*nrdels = -1; // Error
220220
}
221+
zval_ptr_dtor(&retval);
221222
return *nrdels;
222223
}
223224

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
session_gc(): user handler returning non-bool/non-int does not leak memory
3+
--INI--
4+
session.gc_probability=0
5+
session.save_handler=files
6+
--EXTENSIONS--
7+
session
8+
--FILE--
9+
<?php
10+
ob_start();
11+
12+
// Procedural API has no return type enforcement, so gc can return a string
13+
// (reference-counted), which PS_GC_FUNC(user) previously did not free.
14+
session_set_save_handler(
15+
function(string $path, string $name) { return true; },
16+
function() { return true; },
17+
function(string $id): string|false { return ""; },
18+
function(string $id, string $data) { return true; },
19+
function(string $id) { return true; },
20+
function(int $max) { return str_repeat("x", 100); }
21+
);
22+
23+
session_start();
24+
$result = session_gc();
25+
var_dump($result);
26+
session_write_close();
27+
28+
ob_end_flush();
29+
?>
30+
--EXPECTF--
31+
32+
Deprecated: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in %s on line %d
33+
bool(false)

0 commit comments

Comments
 (0)