--- /dev/null
+--TEST--
+Bug #31683 (changes to $name in __get($name) override future parameters)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+class Foo implements ArrayAccess {
+
+ function __get($test) {
+ var_dump($test);
+ $test = 'bug';
+ }
+
+ function __set($test, $val) {
+ var_dump($test);
+ var_dump($val);
+ $test = 'bug';
+ $val = 'bug';
+ }
+
+ function __call($test, $arg) {
+ var_dump($test);
+ $test = 'bug';
+ }
+
+ function offsetget($test) {
+ var_dump($test);
+ $test = 'bug';
+ return 123;
+ }
+
+ function offsetset($test, $val) {
+ var_dump($test);
+ var_dump($val);
+ $test = 'bug';
+ $val = 'bug';
+ }
+
+ function offsetexists($test) {
+ var_dump($test);
+ $test = 'bug';
+ }
+
+ function offsetunset($test) {
+ var_dump($test);
+ $test = 'bug';
+ }
+
+}
+
+$foo = new Foo();
+$a = "ok";
+
+for ($i=0; $i < 2; $i++) {
+ $foo->ok("ok");
+ $foo->ok;
+ $foo->ok = "ok";
+ $x = $foo["ok"];
+ $foo["ok"] = "ok";
+ isset($foo["ok"]);
+ unset($foo["ok"]);
+// $foo[];
+ $foo[] = "ok";
+// isset($foo[]);
+// unset($foo[]);
+ $foo->$a;
+ echo "---\n";
+}
+?>
+--EXPECT--
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+NULL
+string(2) "ok"
+string(2) "ok"
+---
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+string(2) "ok"
+NULL
+string(2) "ok"
+string(2) "ok"
+---
it should return whether the call was successfull or not
*/
+
+ SEPARATE_ARG_IF_REF(member);
+
zend_call_method_with_1_params(&object, ce, &ce->__get, ZEND_GET_FUNC_NAME, &retval, member);
+ zval_ptr_dtor(&member);
+
if (retval) {
retval->refcount--;
}
zval *retval = NULL;
int ret;
zend_class_entry *ce = Z_OBJCE_P(object);
-
+
+ SEPARATE_ARG_IF_REF(member);
value->refcount++;
/* __set handler is called with two arguments:
*/
zend_call_method_with_2_params(&object, ce, &ce->__set, ZEND_SET_FUNC_NAME, &retval, member, value);
+ zval_ptr_dtor(&member);
zval_ptr_dtor(&value);
if (retval && zend_is_true(retval)) {
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
if(offset == NULL) {
/* [] construct */
- zval offset_null;
- INIT_ZVAL(offset_null);
- offset = &offset_null;
+ ALLOC_INIT_ZVAL(offset);
+ } else {
+ SEPARATE_ARG_IF_REF(offset);
}
zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset);
+ zval_ptr_dtor(&offset);
+
if (!retval) {
if (!EG(exception)) {
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
static void zend_std_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
{
zend_class_entry *ce = Z_OBJCE_P(object);
- zval tmp;
-
+
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
if (!offset) {
- INIT_ZVAL(tmp);
- offset = &tmp;
+ ALLOC_INIT_ZVAL(offset);
+ } else {
+ SEPARATE_ARG_IF_REF(offset);
}
zend_call_method_with_2_params(&object, ce, NULL, "offsetset", NULL, offset, value);
+ zval_ptr_dtor(&offset);
} else {
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
}
int result;
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ SEPARATE_ARG_IF_REF(offset);
zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset);
+ zval_ptr_dtor(&offset);
result = i_zend_is_true(retval);
zval_ptr_dtor(&retval);
return result;
zval *retval;
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) {
+ SEPARATE_ARG_IF_REF(offset);
zend_call_method_with_1_params(&object, ce, NULL, "offsetunset", &retval, offset);
+ zval_ptr_dtor(&offset);
zval_ptr_dtor(&retval);
} else {
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);