From ed37ca7369c7891cdbe7795ce96ad46dad7c1d26 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 25 Jun 2017 15:37:29 +0200 Subject: [PATCH] Fixed bug #74810 And also did some general cleanup in ZEND_FUNC_GET_ARGS. --- Zend/tests/bug74810.phpt | 25 ++++++++++++ Zend/zend_vm_def.h | 42 ++++++++++---------- Zend/zend_vm_execute.h | 84 +++++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 Zend/tests/bug74810.phpt diff --git a/Zend/tests/bug74810.phpt b/Zend/tests/bug74810.phpt new file mode 100644 index 0000000000..6c24e4bce8 --- /dev/null +++ b/Zend/tests/bug74810.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #74810: Something odd about ordering of func_get_args() result in 7.2 +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(0) { +} diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 5d4a916971..e3eb337038 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8189,32 +8189,31 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) { USE_OPLINE zend_array *ht; - uint32_t arg_count, first_extra_arg, i, n; - zval *p, *q; + uint32_t arg_count, result_size, skip; arg_count = EX_NUM_ARGS(); - ht = (zend_array *) emalloc(sizeof(zend_array)); if (OP1_TYPE == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - if (arg_count < i) { - i = 0; + skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + if (arg_count < skip) { + result_size = 0; } else { - i = arg_count - i; + result_size = arg_count - skip; } - zend_hash_init(ht, i, NULL, ZVAL_PTR_DTOR, 0); } else { - zend_hash_init(ht, arg_count, NULL, ZVAL_PTR_DTOR, 0); + skip = 0; + result_size = arg_count; } + + ht = (zend_array *) emalloc(sizeof(zend_array)); + zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (arg_count) { - first_extra_arg = EX(func)->op_array.num_args; + + if (result_size) { + uint32_t first_extra_arg = EX(func)->op_array.num_args; zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { - i = 0; - n = 0; - if (OP1_TYPE == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - } + zval *p, *q; + uint32_t i = skip; p = EX_VAR_NUM(i); if (arg_count > first_extra_arg) { while (i < first_extra_arg) { @@ -8228,11 +8227,15 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } - p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); + if (skip < first_extra_arg) { + skip = 0; + } else { + skip -= first_extra_arg; + } + p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); } while (i < arg_count) { q = p; @@ -8245,12 +8248,11 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } } ZEND_HASH_FILL_END(); - ht->nNumOfElements = n; + ht->nNumOfElements = result_size; } ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 01b036bed6..7f43c0dfbf 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8151,32 +8151,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE { USE_OPLINE zend_array *ht; - uint32_t arg_count, first_extra_arg, i, n; - zval *p, *q; + uint32_t arg_count, result_size, skip; arg_count = EX_NUM_ARGS(); - ht = (zend_array *) emalloc(sizeof(zend_array)); if (IS_CONST == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - if (arg_count < i) { - i = 0; + skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + if (arg_count < skip) { + result_size = 0; } else { - i = arg_count - i; + result_size = arg_count - skip; } - zend_hash_init(ht, i, NULL, ZVAL_PTR_DTOR, 0); } else { - zend_hash_init(ht, arg_count, NULL, ZVAL_PTR_DTOR, 0); + skip = 0; + result_size = arg_count; } + + ht = (zend_array *) emalloc(sizeof(zend_array)); + zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (arg_count) { - first_extra_arg = EX(func)->op_array.num_args; + + if (result_size) { + uint32_t first_extra_arg = EX(func)->op_array.num_args; zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { - i = 0; - n = 0; - if (IS_CONST == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - } + zval *p, *q; + uint32_t i = skip; p = EX_VAR_NUM(i); if (arg_count > first_extra_arg) { while (i < first_extra_arg) { @@ -8190,11 +8189,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } - p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); + if (skip < first_extra_arg) { + skip = 0; + } else { + skip -= first_extra_arg; + } + p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); } while (i < arg_count) { q = p; @@ -8207,12 +8210,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } } ZEND_HASH_FILL_END(); - ht->nNumOfElements = n; + ht->nNumOfElements = result_size; } ZEND_VM_NEXT_OPCODE(); } @@ -29237,32 +29239,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS { USE_OPLINE zend_array *ht; - uint32_t arg_count, first_extra_arg, i, n; - zval *p, *q; + uint32_t arg_count, result_size, skip; arg_count = EX_NUM_ARGS(); - ht = (zend_array *) emalloc(sizeof(zend_array)); if (IS_UNUSED == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - if (arg_count < i) { - i = 0; + skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + if (arg_count < skip) { + result_size = 0; } else { - i = arg_count - i; + result_size = arg_count - skip; } - zend_hash_init(ht, i, NULL, ZVAL_PTR_DTOR, 0); } else { - zend_hash_init(ht, arg_count, NULL, ZVAL_PTR_DTOR, 0); + skip = 0; + result_size = arg_count; } + + ht = (zend_array *) emalloc(sizeof(zend_array)); + zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (arg_count) { - first_extra_arg = EX(func)->op_array.num_args; + + if (result_size) { + uint32_t first_extra_arg = EX(func)->op_array.num_args; zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { - i = 0; - n = 0; - if (IS_UNUSED == IS_CONST) { - i = Z_LVAL_P(EX_CONSTANT(opline->op1)); - } + zval *p, *q; + uint32_t i = skip; p = EX_VAR_NUM(i); if (arg_count > first_extra_arg) { while (i < first_extra_arg) { @@ -29276,11 +29277,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } - p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); + if (skip < first_extra_arg) { + skip = 0; + } else { + skip -= first_extra_arg; + } + p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); } while (i < arg_count) { q = p; @@ -29293,12 +29298,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS q = &EG(uninitialized_zval); } ZEND_HASH_FILL_ADD(q); - n++; p++; i++; } } ZEND_HASH_FILL_END(); - ht->nNumOfElements = n; + ht->nNumOfElements = result_size; } ZEND_VM_NEXT_OPCODE(); } -- 2.40.0