]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.0' into PHP-7.1
authorDmitry Stogov <dmitry@zend.com>
Tue, 20 Dec 2016 13:53:06 +0000 (16:53 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 20 Dec 2016 13:53:06 +0000 (16:53 +0300)
* PHP-7.0:
  Fixed bug #73792 (invalid foreach loop hangs script)

1  2 
NEWS
Zend/zend_execute.c

diff --cc NEWS
index f94dd9aa9cd9c5a0b1b33449aa1dd7c8d4102d08,98b88cc3f7601fb255803c247ee4e6d85594f2a1..374dd1c8ea76c34d34190d712e0b77f6444d956a
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,17 -1,13 +1,18 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? 2016 PHP 7.0.15
 +?? ??? 2017, PHP 7.1.1
  
  - Core:
+   . Fixed bug #73792 (invalid foreach loop hangs script). (Dmitry)
 +  . Fixed bug #73686 (Adding settype()ed values to ArrayObject results in
 +    references). (Nikita, Laruence)
    . Fixed bug #73663 ("Invalid opcode 65/16/8" occurs with a variable created
      with list()). (Laruence)
 -  . Fixed bug #73585 (Logging of "Internal Zend error - Missing class
 -    information" missing class name). (Laruence)
 +  . Fixed bug #73727 (ZEND_MM_BITSET_LEN is "undefined symbol" in
 +    zend_bitset.h). (Nikita)
 +
 +- CLI:
 +  . Fixed bug #72555 (CLI output(japanese) on Windows). (Anatol)
  
  - COM:
    . Fixed bug #73679 (DOTNET read access violation using invalid codepage).
index 647428f9592fa08da39c98a463bc343fa3fb0607,dc3db0f9fef0964fcd19938881f5130038bdb173..0b98cab44ba540b5ed99a4b77f916d1c9be7b0ac
@@@ -1131,172 -1311,13 +1131,175 @@@ static zend_never_inline void zend_bina
        }
  }
  
 -static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result)
 +static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
 +{
 +      zend_long offset;
 +
 +try_again:
 +      if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
 +              switch(Z_TYPE_P(dim)) {
 +                      case IS_STRING:
 +                              if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
 +                                      break;
 +                              }
 +                              if (type != BP_VAR_UNSET) {
 +                                      zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
 +                              }
 +                              break;
 +                      case IS_UNDEF:
 +                              zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
 +                      case IS_DOUBLE:
 +                      case IS_NULL:
 +                      case IS_FALSE:
 +                      case IS_TRUE:
 +                              zend_error(E_NOTICE, "String offset cast occurred");
 +                              break;
 +                      case IS_REFERENCE:
 +                              dim = Z_REFVAL_P(dim);
 +                              goto try_again;
 +                      default:
 +                              zend_error(E_WARNING, "Illegal offset type");
 +                              break;
 +              }
 +
 +              offset = _zval_get_long_func(dim);
 +      } else {
 +              offset = Z_LVAL_P(dim);
 +      }
 +
 +      return offset;
 +}
 +
 +static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
 +{
 +      const char *msg = NULL;
 +      const zend_op *opline = EG(current_execute_data)->opline;
 +      const zend_op *end;
 +      uint32_t var;
 +
 +      switch (opline->opcode) {
 +              case ZEND_ASSIGN_ADD:
 +              case ZEND_ASSIGN_SUB:
 +              case ZEND_ASSIGN_MUL:
 +              case ZEND_ASSIGN_DIV:
 +              case ZEND_ASSIGN_MOD:
 +              case ZEND_ASSIGN_SL:
 +              case ZEND_ASSIGN_SR:
 +              case ZEND_ASSIGN_CONCAT:
 +              case ZEND_ASSIGN_BW_OR:
 +              case ZEND_ASSIGN_BW_AND:
 +              case ZEND_ASSIGN_BW_XOR:
 +              case ZEND_ASSIGN_POW:
 +                      msg = "Cannot use assign-op operators with string offsets";
 +                      break;
 +              case ZEND_FETCH_DIM_W:
 +              case ZEND_FETCH_DIM_RW:
 +              case ZEND_FETCH_DIM_FUNC_ARG:
 +              case ZEND_FETCH_DIM_UNSET:
 +                      /* TODO: Encode the "reason" into opline->extended_value??? */
 +                      var = opline->result.var;
 +                      opline++;
 +                      end = EG(current_execute_data)->func->op_array.opcodes +
 +                              EG(current_execute_data)->func->op_array.last;
 +                      while (opline < end) {
 +                              if (opline->op1_type == IS_VAR && opline->op1.var == var) {
 +                                      switch (opline->opcode) {
 +                                              case ZEND_ASSIGN_ADD:
 +                                              case ZEND_ASSIGN_SUB:
 +                                              case ZEND_ASSIGN_MUL:
 +                                              case ZEND_ASSIGN_DIV:
 +                                              case ZEND_ASSIGN_MOD:
 +                                              case ZEND_ASSIGN_SL:
 +                                              case ZEND_ASSIGN_SR:
 +                                              case ZEND_ASSIGN_CONCAT:
 +                                              case ZEND_ASSIGN_BW_OR:
 +                                              case ZEND_ASSIGN_BW_AND:
 +                                              case ZEND_ASSIGN_BW_XOR:
 +                                              case ZEND_ASSIGN_POW:
 +                                                      if (opline->extended_value == ZEND_ASSIGN_OBJ) {
 +                                                              msg = "Cannot use string offset as an object";
 +                                                      } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
 +                                                              msg = "Cannot use string offset as an array";
 +                                                      } else {
 +                                                              msg = "Cannot use assign-op operators with string offsets";
 +                                                      }
 +                                                      break;
 +                                              case ZEND_PRE_INC_OBJ:
 +                                              case ZEND_PRE_DEC_OBJ:
 +                                              case ZEND_POST_INC_OBJ:
 +                                              case ZEND_POST_DEC_OBJ:
 +                                              case ZEND_PRE_INC:
 +                                              case ZEND_PRE_DEC:
 +                                              case ZEND_POST_INC:
 +                                              case ZEND_POST_DEC:
 +                                                      msg = "Cannot increment/decrement string offsets";
 +                                                      break;
 +                                              case ZEND_FETCH_DIM_W:
 +                                              case ZEND_FETCH_DIM_RW:
 +                                              case ZEND_FETCH_DIM_FUNC_ARG:
 +                                              case ZEND_FETCH_DIM_UNSET:
 +                                              case ZEND_ASSIGN_DIM:
 +                                                      msg = "Cannot use string offset as an array";
 +                                                      break;
 +                                              case ZEND_FETCH_OBJ_W:
 +                                              case ZEND_FETCH_OBJ_RW:
 +                                              case ZEND_FETCH_OBJ_FUNC_ARG:
 +                                              case ZEND_FETCH_OBJ_UNSET:
 +                                              case ZEND_ASSIGN_OBJ:
 +                                                      msg = "Cannot use string offset as an object";
 +                                                      break;
 +                                              case ZEND_ASSIGN_REF:
 +                                              case ZEND_ADD_ARRAY_ELEMENT:
 +                                              case ZEND_INIT_ARRAY:
 +                                              case ZEND_MAKE_REF:
 +                                                      msg = "Cannot create references to/from string offsets";
 +                                                      break;
 +                                              case ZEND_RETURN_BY_REF:
 +                                              case ZEND_VERIFY_RETURN_TYPE:
 +                                                      msg = "Cannot return string offsets by reference";
 +                                                      break;
 +                                              case ZEND_UNSET_DIM:
 +                                              case ZEND_UNSET_OBJ:
 +                                                      msg = "Cannot unset string offsets";
 +                                                      break;
 +                                              case ZEND_YIELD:
 +                                                      msg = "Cannot yield string offsets by reference";
 +                                                      break;
 +                                              case ZEND_SEND_REF:
 +                                              case ZEND_SEND_VAR_EX:
 +                                                      msg = "Only variables can be passed by reference";
 +                                                      break;
++                                              case ZEND_FE_RESET_RW:
++                                                      msg = "Cannot iterate on string offsets by reference";
++                                                      break;
 +                                              EMPTY_SWITCH_DEFAULT_CASE();
 +                                      }
 +                                      break;
 +                              }
 +                              if (opline->op2_type == IS_VAR && opline->op2.var == var) {
 +                                      ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF);
 +                                      msg = "Cannot create references to/from string offsets";
 +                                      break;
 +                              }
 +                      }
 +                      break;
 +              EMPTY_SWITCH_DEFAULT_CASE();
 +      }
 +      ZEND_ASSERT(msg != NULL);
 +      zend_throw_error(NULL, msg);
 +}
 +
 +static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value, zval *result)
  {
        zend_string *old_str;
 +      zend_uchar c;
 +      size_t string_len;
 +      zend_long offset;
  
 -      if (offset < 0) {
 +      offset = zend_check_string_offset(dim, BP_VAR_W);
 +      if (offset < (zend_long)(-Z_STRLEN_P(str))) {
 +              /* Error on negative offset */
                zend_error(E_WARNING, "Illegal string offset:  " ZEND_LONG_FMT, offset);
 -              zend_string_release(Z_STR_P(str));
                if (result) {
                        ZVAL_NULL(result);
                }