Merge branch 'PHP-5.6' into PHP-7.0
authorDmitry Stogov <dmitry@zend.com>
Tue, 18 Oct 2016 12:04:49 +0000 (15:04 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 18 Oct 2016 12:04:49 +0000 (15:04 +0300)
* PHP-5.6:
  Fixed bug #73337 (try/catch not working with two exceptions inside a same operation)

1  2 
NEWS
Zend/zend_execute_API.c

diff --cc NEWS
index 12350672af678f4378669239454d02b4e2d996b3,fc2e52c11e0b13e17f64b4d4cdd0b95a28e2f818..be20d3ba963fe62543b5fa87ba553094d088946b
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,17 -1,12 +1,19 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? 2016, PHP 5.6.28
 +?? ??? 2016 PHP 7.0.13
  
  - Core:
 +  . Fixed bug #73181 (parse_str() without a second argument leads to crash).
 +    (Nikita)
 +  . Fixed bug #66773 (Autoload with Opcache allows importing conflicting class
 +    name to namespace). (Nikita)
 +  . Fixed bug #66862 ((Sub-)Namespaces unexpected behaviour). (Nikita)
 +  . Fix pthreads detection when cross-compiling (ffontaine)
 +  . Fixed bug #73215 (uniqid() should use better random source). (Yasuo)
+   . Fixed bug #73337 (try/catch not working with two exceptions inside a same
+     operation). (Dmitry)
  
 --GD:
 +- GD:
    . Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb)
    . Fixed bug #73272 (imagescale() is not affected by, but affects
      imagesetinterpolation()). (cmb)
index 194f16df48b80ce7f208ef0c3eaff384938de00b,bf754d25df2d3fc257364240a5e1d1bf5a8c8682..f96cac5f097603a45e1f4fdac03e40c07fa7d104
@@@ -815,70 -740,117 +815,73 @@@ int zend_call_function(zend_fcall_info 
                                        return FAILURE;
                                }
  
 -                              ALLOC_ZVAL(new_zval);
 -                              *new_zval = **fci->params[i];
 -                              zval_copy_ctor(new_zval);
 -                              Z_SET_REFCOUNT_P(new_zval, 1);
 -                              Z_DELREF_PP(fci->params[i]);
 -                              *fci->params[i] = new_zval;
 +                              ZVAL_NEW_REF(arg, arg);
                        }
 -                      Z_ADDREF_PP(fci->params[i]);
 -                      Z_SET_ISREF_PP(fci->params[i]);
 -                      param = *fci->params[i];
 -              } else if (PZVAL_IS_REF(*fci->params[i]) &&
 -                         /* don't separate references for __call */
 -                         (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
 -                      ALLOC_ZVAL(param);
 -                      *param = **(fci->params[i]);
 -                      INIT_PZVAL(param);
 -                      zval_copy_ctor(param);
 -              } else if (*fci->params[i] != &EG(uninitialized_zval)) {
 -                      Z_ADDREF_PP(fci->params[i]);
 -                      param = *fci->params[i];
 +                      Z_ADDREF_P(arg);
                } else {
 -                      ALLOC_ZVAL(param);
 -                      *param = **(fci->params[i]);
 -                      INIT_PZVAL(param);
 +                      if (Z_ISREF_P(arg) &&
 +                          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
 +                              /* don't separate references for __call */
 +                              arg = Z_REFVAL_P(arg);
 +                      }
 +                      if (Z_OPT_REFCOUNTED_P(arg)) {
 +                              Z_ADDREF_P(arg);
 +                      }
                }
 -              zend_vm_stack_push(param TSRMLS_CC);
 +              param = ZEND_CALL_ARG(call, i+1);
 +              ZVAL_COPY_VALUE(param, arg);
        }
  
 -      EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
 -      zend_vm_stack_push((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
 -
 -      current_scope = EG(scope);
        EG(scope) = calling_scope;
 -
 -      current_this = EG(This);
 -
 -      current_called_scope = EG(called_scope);
 -      if (called_scope) {
 -              EG(called_scope) = called_scope;
 -      } else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) {
 -              EG(called_scope) = NULL;
 +      if (func->common.fn_flags & ZEND_ACC_STATIC) {
 +              fci->object = NULL;
        }
 +      Z_OBJ(call->This) = fci->object;
  
 -      if (fci->object_ptr) {
 -              if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
 -                      EG(This) = NULL;
 -              } else {
 -                      EG(This) = fci->object_ptr;
 -
 -                      if (!PZVAL_IS_REF(EG(This))) {
 -                              Z_ADDREF_P(EG(This)); /* For $this pointer */
 -                      } else {
 -                              zval *this_ptr;
 -
 -                              ALLOC_ZVAL(this_ptr);
 -                              *this_ptr = *EG(This);
 -                              INIT_PZVAL(this_ptr);
 -                              zval_copy_ctor(this_ptr);
 -                              EG(This) = this_ptr;
 -                      }
 -              }
 -      } else {
 -              EG(This) = NULL;
 +      if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
 +              ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT);
 +              GC_REFCOUNT((zend_object*)func->op_array.prototype)++;
 +              ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE);
        }
  
 -      EX(prev_execute_data) = EG(current_execute_data);
 -      EG(current_execute_data) = &execute_data;
 -
 -      if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
 -              calling_symbol_table = EG(active_symbol_table);
 -              EG(scope) = EX(function_state).function->common.scope;
 -              if (fci->symbol_table) {
 -                      EG(active_symbol_table) = fci->symbol_table;
 -              } else {
 -                      EG(active_symbol_table) = NULL;
 -              }
 -
 -              original_return_value = EG(return_value_ptr_ptr);
 -              original_op_array = EG(active_op_array);
 -              EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
 -              EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 -              original_opline_ptr = EG(opline_ptr);
 +      /* PHP-7 doesn't support symbol_table substitution for functions */
 +      ZEND_ASSERT(fci->symbol_table == NULL);
  
 -              if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
 -                      *fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
 -              } else {
 +      if (func->type == ZEND_USER_FUNCTION) {
 +              int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
 +              EG(scope) = func->common.scope;
 +              call->symbol_table = fci->symbol_table;
 +              if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
+                       const zend_op *current_opline_before_exception = EG(opline_before_exception);
 -                      zend_execute(EG(active_op_array) TSRMLS_CC);
 +                      zend_init_execute_data(call, &func->op_array, fci->retval);
 +                      zend_execute_ex(call);
+                       EG(opline_before_exception) = current_opline_before_exception;
 +              } else {
 +                      zend_generator_create_zval(call, &func->op_array, fci->retval);
                }
 -
 -              if (!fci->symbol_table && EG(active_symbol_table)) {
 -                      zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
 +              if (call_via_handler) {
 +                      /* We must re-initialize function again */
 +                      fci_cache->initialized = 0;
                }
 -              EG(active_symbol_table) = calling_symbol_table;
 -              EG(active_op_array) = original_op_array;
 -              EG(return_value_ptr_ptr)=original_return_value;
 -              EG(opline_ptr) = original_opline_ptr;
 -      } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
 -              int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
 -              ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
 -              if (EX(function_state).function->common.scope) {
 -                      EG(scope) = EX(function_state).function->common.scope;
 +      } else if (func->type == ZEND_INTERNAL_FUNCTION) {
 +              int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
 +              ZVAL_NULL(fci->retval);
 +              if (func->common.scope) {
 +                      EG(scope) = func->common.scope;
                }
 +              call->prev_execute_data = EG(current_execute_data);
 +              call->return_value = NULL; /* this is not a constructor call */
 +              EG(current_execute_data) = call;
                if (EXPECTED(zend_execute_internal == NULL)) {
                        /* saves one function call if zend_execute_internal is not used */
 -                      EX(function_state).function->internal_function.handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
 +                      func->internal_function.handler(call, fci->retval);
                } else {
 -                      zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC);
 +                      zend_execute_internal(call, fci->retval);
                }
 +              EG(current_execute_data) = call->prev_execute_data;
 +              zend_vm_stack_free_args(call);
 +
                /*  We shouldn't fix bad extensions here,
                        because it can break proper ones (Bug #34045)
                if (!EX(function_state).function->common.return_reference)