]> granicus.if.org Git - php/commitdiff
Properly cleanup on wrong ZEND_OVERLOADED_FUNCTION call
authorDmitry Stogov <dmitry@zend.com>
Tue, 22 Sep 2015 20:51:30 +0000 (23:51 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 22 Sep 2015 20:51:30 +0000 (23:51 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 3d01572f9fe5f44c7b8bf6dd822d2b2387551883..62d9bbf98c5624866c3abd982681d3315418a5af 100644 (file)
@@ -3806,33 +3806,29 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
                        ZEND_VM_C_GOTO(fcall_end);
                }
        } else { /* ZEND_OVERLOADED_FUNCTION */
-               EG(scope) = fbc->common.scope;
-
-               ZVAL_NULL(EX_VAR(opline->result.var));
-
                /* Not sure what should be done here if it's a static method */
                object = Z_OBJ(call->This);
-               if (EXPECTED(object != NULL)) {
-                       call->prev_execute_data = execute_data;
-                       EG(current_execute_data) = call;
-                       object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var));
-                       EG(current_execute_data) = call->prev_execute_data;
-               } else {
-                       zend_throw_error(NULL, "Cannot call overloaded function for non-object");
-#if 0
-                       //TODO: implement clean exit ???
+               if (UNEXPECTED(object == NULL)) {
                        zend_vm_stack_free_args(call);
-
-                       zend_vm_stack_free_call_frame(call);
-
                        if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
                                zend_string_release(fbc->common.function_name);
                        }
                        efree(fbc);
-#endif
+                       zend_vm_stack_free_call_frame(call);
+
+                       zend_throw_error(NULL, "Cannot call overloaded function for non-object");
                        HANDLE_EXCEPTION();
                }
 
+               EG(scope) = fbc->common.scope;
+
+               ZVAL_NULL(EX_VAR(opline->result.var));
+
+               call->prev_execute_data = execute_data;
+               EG(current_execute_data) = call;
+               object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var));
+               EG(current_execute_data) = call->prev_execute_data;
+
                zend_vm_stack_free_args(call);
 
                if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
index 7d1d726a8f08fa3ca98875dcb8f63d6cd28a3dab..b9fa6f586ffccbbaee205bc0331aa453992e04e0 100644 (file)
@@ -860,33 +860,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC
                        goto fcall_end;
                }
        } else { /* ZEND_OVERLOADED_FUNCTION */
-               EG(scope) = fbc->common.scope;
-
-               ZVAL_NULL(EX_VAR(opline->result.var));
-
                /* Not sure what should be done here if it's a static method */
                object = Z_OBJ(call->This);
-               if (EXPECTED(object != NULL)) {
-                       call->prev_execute_data = execute_data;
-                       EG(current_execute_data) = call;
-                       object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var));
-                       EG(current_execute_data) = call->prev_execute_data;
-               } else {
-                       zend_throw_error(NULL, "Cannot call overloaded function for non-object");
-#if 0
-                       //TODO: implement clean exit ???
+               if (UNEXPECTED(object == NULL)) {
                        zend_vm_stack_free_args(call);
-
-                       zend_vm_stack_free_call_frame(call);
-
                        if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
                                zend_string_release(fbc->common.function_name);
                        }
                        efree(fbc);
-#endif
+                       zend_vm_stack_free_call_frame(call);
+
+                       zend_throw_error(NULL, "Cannot call overloaded function for non-object");
                        HANDLE_EXCEPTION();
                }
 
+               EG(scope) = fbc->common.scope;
+
+               ZVAL_NULL(EX_VAR(opline->result.var));
+
+               call->prev_execute_data = execute_data;
+               EG(current_execute_data) = call;
+               object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var));
+               EG(current_execute_data) = call->prev_execute_data;
+
                zend_vm_stack_free_args(call);
 
                if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {