summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-04-16 12:21:16 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-04-16 12:21:16 +0200
commit2bdd212887d4ee3fd606df18b12038567f33b90b (patch)
tree61b2c10aec56e1900e0dbb4f93fe97fd3500ac68
parentc60a852e3ca0350441ec7eac5d82b9279d550d82 (diff)
parentf9a755d0d27eebd02fdeb9b1750aaca70b15f409 (diff)
downloadphp-git-2bdd212887d4ee3fd606df18b12038567f33b90b.tar.gz
Merge branch 'PHP-7.3' into PHP-7.4
-rw-r--r--Zend/zend_hash.c7
-rw-r--r--Zend/zend_hash.h3
-rw-r--r--ext/standard/array.c1
3 files changed, 8 insertions, 3 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 88eafa6d10..5358f0d7d0 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -504,6 +504,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
&& EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
+ ZEND_ASSERT(HT_ITERATORS_COUNT(iter->ht) != 0);
HT_DEC_ITERATORS_COUNT(iter->ht);
}
iter->ht = NULL;
@@ -2023,7 +2024,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
target->nTableSize = HT_MIN_SIZE;
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
} else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {
- HT_FLAGS(target) = HT_FLAGS(source);
+ HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
target->nTableMask = source->nTableMask;
target->nNumUsed = source->nNumUsed;
target->nNumOfElements = source->nNumOfElements;
@@ -2033,7 +2034,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
target->nInternalPointer = source->nInternalPointer;
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
} else if (HT_FLAGS(source) & HASH_FLAG_PACKED) {
- HT_FLAGS(target) = HT_FLAGS(source);
+ HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
target->nTableMask = HT_MIN_MASK;
target->nNumUsed = source->nNumUsed;
target->nNumOfElements = source->nNumOfElements;
@@ -2052,7 +2053,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
zend_array_dup_packed_elements(source, target, 1);
}
} else {
- HT_FLAGS(target) = HT_FLAGS(source);
+ HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
target->nTableMask = source->nTableMask;
target->nNextFreeElement = source->nNextFreeElement;
target->nInternalPointer =
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 0cc34ddd47..3341427428 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -40,6 +40,9 @@
#define HASH_FLAG_HAS_EMPTY_IND (1<<5)
#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
+/* Only the low byte are real flags */
+#define HASH_FLAG_MASK 0xff
+
#define HT_FLAGS(ht) (ht)->u.flags
#define HT_INVALIDATE(ht) do { \
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 2658ad68f5..e257caa3c8 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -3145,6 +3145,7 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H
}
/* replace HashTable data */
+ HT_SET_ITERATORS_COUNT(&out_hash, HT_ITERATORS_COUNT(in_hash));
HT_SET_ITERATORS_COUNT(in_hash, 0);
in_hash->pDestructor = NULL;
zend_hash_destroy(in_hash);