SEND_UNPACK on iterators was duplicating references in-place,
which effectively leaks the original value and causes an off-by-one
refcount on the duplicated value.
Replace this with a deref, as an actual duplication is not even
needed in this case.
- Core:
. Fixed bug #75679 (Path 260 character problem). (Anatol)
+ . Fixed bug #75786 (segfault when using spread operator on generator passed
+ by reference). (Nikita)
- Opcache:
. Fixed bug #75720 (File cache not populated after SHM runs full). (Dmitry)
--- /dev/null
+--TEST--
+Bug #75786: segfault when using spread operator on generator passed by reference
+--FILE--
+<?php
+
+function &gen($items) {
+ foreach ($items as $key => &$value) {
+ yield $key => $value;
+ }
+}
+
+var_dump(...gen(['a', 'b', 'c']));
+
+?>
+--EXPECT--
+string(1) "a"
+string(1) "b"
+string(1) "c"
);
}
- if (Z_ISREF_P(arg)) {
- ZVAL_DUP(arg, Z_REFVAL_P(arg));
- } else {
- if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
- }
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
top = ZEND_CALL_ARG(EX(call), arg_num);
);
}
- if (Z_ISREF_P(arg)) {
- ZVAL_DUP(arg, Z_REFVAL_P(arg));
- } else {
- if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg);
- }
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
top = ZEND_CALL_ARG(EX(call), arg_num);