--- /dev/null
+--TEST--
+Bug #70685: Segfault for getClosure() internal method rebind with invalid $this
+--FILE--
+<?php
+
+class cls {}
+
+$c = (new ReflectionMethod('SplStack', 'count'))->getClosure(new SplStack);
+$c = $c->bindTo(new cls);
+var_dump($c);
+
+$c = (new ReflectionMethod('SplStack', 'count'))->getClosure(new SplStack);
+$c = $c->bindTo(new SplStack, 'cls');
+var_dump($c);
+
+?>
+--EXPECTF--
+Warning: Cannot bind internal method SplDoublyLinkedList::count() to object of class cls in %s on line %d
+NULL
+
+Warning: Cannot bind function SplDoublyLinkedList::count to scope class cls in %s on line %d
+NULL
ce = closure->func.common.scope;
}
+ /* verify that we aren't binding internal function to a wrong scope */
+ if (closure->func.type == ZEND_INTERNAL_FUNCTION && closure->func.common.scope != NULL) {
+ if (ce && !instanceof_function(ce, closure->func.common.scope TSRMLS_CC)) {
+ zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", closure->func.common.scope->name, closure->func.common.function_name, ce->name);
+ return;
+ }
+ if (ce && newthis && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0 &&
+ !instanceof_function(Z_OBJCE_P(newthis), closure->func.common.scope TSRMLS_CC)) {
+ zend_error(E_WARNING, "Cannot bind internal method %s::%s() to object of class %s", closure->func.common.scope->name, closure->func.common.function_name, Z_OBJCE_P(newthis)->name);
+ return;
+ }
+ }
+
zend_create_closure(return_value, &closure->func, ce, newthis TSRMLS_CC);
}
/* }}} */
closure->func.op_array.run_time_cache = NULL;
(*closure->func.op_array.refcount)++;
} else {
- /* verify that we aren't binding internal function to a wrong scope */
- if(func->common.scope != NULL) {
- if(scope && !instanceof_function(scope, func->common.scope TSRMLS_CC)) {
- zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name, func->common.function_name, scope->name);
- scope = NULL;
- }
- if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 &&
- !instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope TSRMLS_CC)) {
- zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name, func->common.function_name, Z_OBJCE_P(this_ptr)->name);
- scope = NULL;
- this_ptr = NULL;
- }
- } else {
+ if (!func->common.scope) {
/* if it's a free function, we won't set scope & this since they're meaningless */
this_ptr = NULL;
scope = NULL;