Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ PHP NEWS
for grouping. (Klaas Skelte van der Werf)
. Fixed bug GH-24265 (Unwind/GracefulExit discarded in
zend_fiber_execute()). (David Carlier)
. Fixed bug GH-24668 (zend_set_local_var() leaks the previous value of an
existing CV). (yasu20200121web-prog, lazerg)

- Date:
. Fixed bug GH-20503 (Assertion failure with ext/date DateInterval property
Expand Down
7 changes: 6 additions & 1 deletion Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,10 @@ ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool for
if (ZSTR_H(*str) == h &&
zend_string_equal_content(*str, name)) {
zval *var = EX_VAR_NUM(str - op_array->vars);
zval garbage;
ZVAL_COPY_VALUE(&garbage, var);
ZVAL_COPY_VALUE(var, value);
zval_ptr_dtor(&garbage);
return SUCCESS;
}
str++;
Expand Down Expand Up @@ -2002,8 +2005,10 @@ ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval *
if (ZSTR_H(*str) == h &&
zend_string_equals_cstr(*str, name, len)) {
zval *var = EX_VAR_NUM(str - op_array->vars);
zval_ptr_dtor(var);
zval garbage;
ZVAL_COPY_VALUE(&garbage, var);
ZVAL_COPY_VALUE(var, value);
zval_ptr_dtor(&garbage);
return SUCCESS;
}
str++;
Expand Down
18 changes: 18 additions & 0 deletions ext/zend_test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,24 @@ static ZEND_FUNCTION(zend_new_singleton_array)
array_init_singleton(return_value);
}

static ZEND_FUNCTION(zend_test_set_local_var)
{
zend_string *name;
zval *value;

ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_STR(name)
Z_PARAM_ZVAL(value)
ZEND_PARSE_PARAMETERS_END();

Z_TRY_ADDREF_P(value);
if (zend_set_local_var(name, value, false) == FAILURE) {
zval_ptr_dtor(value);
RETURN_FALSE;
}
RETURN_TRUE;
}

static zend_object *zend_test_class_new(zend_class_entry *class_type)
{
zend_object *obj = zend_objects_new(class_type);
Expand Down
2 changes: 2 additions & 0 deletions ext/zend_test/test.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ function zend_test_gh19792(): void {}
function zend_test_handle_post_data(mixed $stream, string $content_type, int $content_length): void {}

function zend_new_singleton_array(): array {}

function zend_test_set_local_var(string $name, mixed $value): bool {}
}

namespace ZendTestNS {
Expand Down
9 changes: 8 additions & 1 deletion ext/zend_test/test_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions ext/zend_test/tests/gh24668.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--TEST--
GH-24668 (zend_set_local_var() leaks the previous value of an existing CV)
--EXTENSIONS--
zend_test
--FILE--
<?php

class Dtor {
public function __destruct() {
echo "dtor\n";
$GLOBALS['trace'] = debug_backtrace();
}
}

function test($a) {
var_dump(zend_test_set_local_var('a', 42));
var_dump($a);
}

test([new Dtor]);
var_dump($trace[2]['args']);

?>
--EXPECT--
dtor
bool(true)
int(42)
array(1) {
[0]=>
int(42)
}
Loading