]> granicus.if.org Git - php/commitdiff
Fixed possible crash on Zend/tests/bug71154.phpt
authorDmitry Stogov <dmitry@zend.com>
Mon, 21 Dec 2015 12:57:53 +0000 (15:57 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 21 Dec 2015 12:57:53 +0000 (15:57 +0300)
Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 8192221c8ecac4a4063df94b200209d920efc0cc..d570a1344699ffb37a596669476e04b8646ee3cb 100644 (file)
@@ -386,6 +386,30 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTab
        return iter->pos;
 }
 
+ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval *array)
+{
+       HashTable *ht = Z_ARRVAL_P(array);
+       HashTableIterator *iter = EG(ht_iterators) + idx;
+
+       ZEND_ASSERT(idx != (uint32_t)-1);
+       if (iter->pos == HT_INVALID_IDX) {
+               return HT_INVALID_IDX;
+       } else if (UNEXPECTED(iter->ht != ht)) {
+               if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
+                               && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
+                       iter->ht->u.v.nIteratorsCount--;
+               }
+               SEPARATE_ARRAY(array);
+               ht = Z_ARRVAL_P(array);
+               if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
+                       ht->u.v.nIteratorsCount++;
+               }
+               iter->ht = ht;
+               iter->pos = ht->nInternalPointer;
+       }
+       return iter->pos;
+}
+
 ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
 {
        HashTableIterator *iter = EG(ht_iterators) + idx;
index 9fe99ac919a2f18ec4d846799ea6ce5612fd4211..b800bb5e765ef03b36c32477519f4889aa3542c4 100644 (file)
@@ -225,6 +225,7 @@ ZEND_API int ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t l
 
 ZEND_API uint32_t     ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos);
 ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTable *ht);
+ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval *array);
 ZEND_API void         ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx);
 ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start);
 ZEND_API void         ZEND_FASTCALL _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
index f02a0e824825d6abf4c8f4f501897a419ef06da7..fd7aa92b0de8c6cbb03037c1fe9554076052f60e 100644 (file)
@@ -6182,8 +6182,8 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY)
 
        ZVAL_DEREF(array);
        if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
+               pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array);
                fe_ht = Z_ARRVAL_P(array);
-               pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
                p = fe_ht->arData + pos;
                while (1) {
                        if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
index 52a122c94a20d7f0b7f8da4da738d2b88dfd125c..d1814a037ccb1d9ff52bfd2fab3279e3de558f43 100644 (file)
@@ -15957,8 +15957,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z
 
        ZVAL_DEREF(array);
        if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
+               pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array);
                fe_ht = Z_ARRVAL_P(array);
-               pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
                p = fe_ht->arData + pos;
                while (1) {
                        if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {