Skip to content

Commit cdb7aaf

Browse files
committed
Fix memory leak(null coalescing operator with Spl hash)
The SEPARATE_ARG_IF_REF macro increased the refcount of the object passed as a key. However, when the key did not exist in the ArrayAccess implementation, the code returned early without trying to decrement the refcount. Add a test of `??` succeeding+failing on a SplObjectStorage instance.
1 parent 60574ea commit cdb7aaf

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

Zend/zend_object_handlers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,11 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type, zval *rv) /*
736736
if (type == BP_VAR_IS) {
737737
zend_call_method_with_1_params(object, ce, NULL, "offsetexists", rv, offset);
738738
if (UNEXPECTED(Z_ISUNDEF_P(rv))) {
739+
zval_ptr_dtor(offset);
739740
return NULL;
740741
}
741742
if (!i_zend_is_true(rv)) {
743+
zval_ptr_dtor(offset);
742744
zval_ptr_dtor(rv);
743745
return &EG(uninitialized_zval);
744746
}

ext/spl/tests/observer_010.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
SPL: SplObjectStorage null coalescing operator memory leak
3+
--FILE--
4+
<?php
5+
// In maintainer zts mode, this should no longer
6+
// detect memory leaks for the objects
7+
$a = new stdClass();
8+
$b = new stdClass();
9+
$map = new SplObjectStorage();
10+
$map[$a] = 'foo';
11+
var_dump($map[$b] ?? null);
12+
var_dump($map[$a] ?? null);
13+
--EXPECTF--
14+
NULL
15+
string(3) "foo"

0 commit comments

Comments
 (0)