Skip to content

Commit 0acde11

Browse files
Girgiasarshidkv12
andcommitted
ext/session: Fix memory leak due to multiple exception happening during session abort
Closes GH-21200 Co-authored-by: arshidkv12 <arshidkv12@gmail.com>
1 parent 6d97fd6 commit 0acde11

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ PHP NEWS
99
. Fixed re-entrancy issue on php_pcre_match_impl, php_pcre_replace_impl,
1010
php_pcre_split_impl, and php_pcre_grep_impl. (David Carlier)
1111

12+
- Session:
13+
. Fix memory leak due to multiple exception happening during session abort.
14+
(arshidkv12)
15+
1216
- SNMP:
1317
. Fixed bug GH-21336 (SNMP::setSecurity() undefined behavior with
1418
NULL arguments). (David Carlier)

ext/session/session.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "ext/standard/url_scanner_ex.h"
4242
#include "ext/standard/info.h"
4343
#include "zend_smart_str.h"
44+
#include "zend_exceptions.h"
4445
#include "ext/standard/url.h"
4546
#include "ext/standard/basic_functions.h"
4647
#include "ext/standard/head.h"
@@ -1743,8 +1744,16 @@ PHPAPI php_session_status php_get_session_status(void)
17431744
static zend_result php_session_abort(void) /* {{{ */
17441745
{
17451746
if (PS(session_status) == php_session_active) {
1746-
if (PS(mod_data) || PS(mod_user_implemented)) {
1747+
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(mod)->s_close) {
1748+
zend_object *old_exception = EG(exception);
1749+
EG(exception) = NULL;
1750+
17471751
PS(mod)->s_close(&PS(mod_data));
1752+
if (!EG(exception)) {
1753+
EG(exception) = old_exception;
1754+
} else if (old_exception) {
1755+
zend_exception_set_previous(EG(exception), old_exception);
1756+
}
17481757
}
17491758
PS(session_status) = php_session_none;
17501759
return SUCCESS;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
SessionHandler::validateId must return bool
3+
--INI--
4+
session.use_strict_mode=1
5+
--EXTENSIONS--
6+
session
7+
--SKIPIF--
8+
<?php include('skipif.inc'); ?>
9+
--FILE--
10+
<?php
11+
class MySession extends SessionHandler {
12+
public function validateId($key) {
13+
return null;
14+
}
15+
}
16+
17+
$handler = new MySession();
18+
19+
try {
20+
session_set_save_handler($handler);
21+
session_start();
22+
} catch (TypeError $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
26+
session_write_close();
27+
28+
try {
29+
session_start();
30+
} catch (Throwable $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
?>
34+
--EXPECTF--
35+
Session id must be a string

ext/session/tests/user_session_module/session_set_save_handler_class_012.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ var_dump(session_id(), $oldHandler, ini_get('session.save_handler'), $handler->i
4343
--EXPECTF--
4444
*** Testing session_set_save_handler() : incorrect arguments for existing handler open ***
4545
Open:
46+
47+
Warning: SessionHandler::close(): Parent session handler is not open in %s on line %d
4648
SessionHandler::open() expects exactly 2 arguments, 0 given
4749

4850
Warning: Undefined global variable $_SESSION in %s on line %d

0 commit comments

Comments
 (0)