summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-04-17 14:23:31 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-04-17 14:24:44 +0200
commit7352213b386658d5dc987cdf5c975fdf5c0bd563 (patch)
tree7fe63c886de50fd9f0d9adf13554eae6dd033bad
parent7574823911cc0407e4ed6209bccf3908afd4c46f (diff)
downloadphp-git-7352213b386658d5dc987cdf5c975fdf5c0bd563.tar.gz
Early return if variadic type check fails
Don't check all the remaining arguments after one check failed. I don't think this makes an observable behavior difference, because we already suppress duplicate exceptions in argument type error reporting.
-rw-r--r--Zend/zend_hash.h6
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h6
3 files changed, 15 insertions, 3 deletions
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 4d3fffd596..289b9a3349 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -1112,13 +1112,17 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
ZEND_HASH_FILL_NEXT(); \
} while (0)
-#define ZEND_HASH_FILL_END() \
+#define ZEND_HASH_FILL_FINISH() do { \
__fill_ht->nNumUsed = __fill_idx; \
__fill_ht->nNumOfElements = __fill_idx; \
__fill_ht->nNextFreeElement = __fill_idx; \
__fill_ht->nInternalPointer = 0; \
} while (0)
+#define ZEND_HASH_FILL_END() \
+ ZEND_HASH_FILL_FINISH(); \
+ } while (0)
+
static zend_always_inline zval *_zend_hash_append_ex(HashTable *ht, zend_string *key, zval *zv, int interned)
{
uint32_t idx = ht->nNumUsed++;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3420344517..0797322a86 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5162,7 +5162,11 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT)
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value));
+ if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
+ ZEND_HASH_FILL_FINISH();
+ HANDLE_EXCEPTION();
+ }
+
if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
ZEND_HASH_FILL_ADD(param);
param++;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 46b23f3839..33e97f2b04 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3134,7 +3134,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value));
+ if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
+ ZEND_HASH_FILL_FINISH();
+ HANDLE_EXCEPTION();
+ }
+
if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
ZEND_HASH_FILL_ADD(param);
param++;