]> granicus.if.org Git - php/commitdiff
Fixed bug #50816 (Using class constants in array definition fails).
authorDmitry Stogov <dmitry@php.net>
Mon, 1 Aug 2011 11:21:23 +0000 (11:21 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 1 Aug 2011 11:21:23 +0000 (11:21 +0000)
NEWS
Zend/tests/bug45742.phpt
Zend/tests/bug50816.phpt [new file with mode: 0644]
Zend/zend_hash.c

diff --git a/NEWS b/NEWS
index 3cd64f2d2a859c812dc1fc9b5a27fdb50bec94ff..cb3d8a653f23b67208ed97ce8efaa0a3bc2d25cf 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ PHP                                                                        NEWS
 - Core
   . Fix bug #55295 [NEW]: popen_ex on windows, fixed possible heap overflow
     (Pierre)
+  . Fixed bug #50816 (Using class constants in array definition fails).
+    (Pierrick, Dmitry)
 
 14 Jul 2011, PHP 5.3.7 RC3
 - Zend Engine:
index b21e093049eacd255049eb9d6e12100e1c33f833..bde690b39acbfc3e6ebd169918d693d2b09c5e73 100644 (file)
@@ -20,5 +20,5 @@ var_dump( ArrayProperty::$array );
 --EXPECT--
 array(1) {
   [1]=>
-  int(23)
+  int(42)
 }
diff --git a/Zend/tests/bug50816.phpt b/Zend/tests/bug50816.phpt
new file mode 100644 (file)
index 0000000..98a8938
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+Bug #50816 (Using class constants in array definition fails)
+--FILE--
+<?php
+define("ONE", 1);
+define("TWO", 1);
+
+class Foo {
+  const ONE = 1;
+  const TWO = 1;
+
+  public static $mapWithConst = array(self::ONE => 'one', self::TWO => 'two',);
+
+  public static $mapWithConst1 = array(1 => 'one', self::TWO => 'two',);
+  public static $mapWithConst2 = array(self::ONE => 'one', 1 => 'two',);
+
+  public static $mapWithoutConst = array(1 => 'one', 1 => 'two',);
+}
+
+$mapWithConst = array(1 => 'one', 1 => 'two',);
+
+$mapWithoutConst = array(Foo::ONE => 'one', Foo::TWO => 'two',);
+$mapWithoutConst0 = array(1 => 'one', 1 => 'two',);
+$mapWithoutConst1 = array(ONE => 'one', 1 => 'two',);
+$mapWithoutConst2 = array(1 => 'one', TWO => 'two',);
+$mapWithoutConst3 = array(ONE => 'one', TWO => 'two',);
+
+var_dump(Foo::$mapWithConst[1]);
+var_dump(Foo::$mapWithConst1[1]);
+var_dump(Foo::$mapWithConst2[1]);
+var_dump(Foo::$mapWithoutConst[1]);
+var_dump($mapWithConst[1]);
+var_dump($mapWithoutConst[1]);
+var_dump($mapWithoutConst0[1]);
+var_dump($mapWithoutConst1[1]);
+var_dump($mapWithoutConst2[1]);
+var_dump($mapWithoutConst3[1]);
+--EXPECT--
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
+string(3) "two"
index be514ffedfa2fe95bf8d13c50f4e616522c3bd5c..66fa60d9585a5ad79b3f0ab01fe644bf9ce69295 100644 (file)
@@ -1173,7 +1173,7 @@ ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosi
  */
 ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos)
 {
-       Bucket *p;
+       Bucket *p, *q;
 
        p = pos ? (*pos) : ht->pInternalPointer;
 
@@ -1186,100 +1186,124 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
                                return SUCCESS;
                        }
 
-                       if (mode != HASH_UPDATE_KEY_ANYWAY) {
-                               Bucket *q = ht->arBuckets[num_index & ht->nTableMask];
-                               int found = 0;
-
-                               while (q != NULL) {
-                                       if (q == p) {
-                                               found = 1;
-                                       } else if (!q->nKeyLength && q->h == num_index) {
-                                               if (found) {
-                                                       if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
-                                                               break;
-                                                       } else {
-                                                               if (p->nKeyLength) {
-                                                                       zend_hash_del(ht, p->arKey, p->nKeyLength);
-                                                               } else {
-                                                                       zend_hash_index_del(ht, p->h);
-                                                               }
-                                                               return FAILURE;
-                                                       }
-                                               } else {
-                                                       if (mode & HASH_UPDATE_KEY_IF_AFTER) {
-                                                               break;
-                                                       } else {
-                                                               if (p->nKeyLength) {
-                                                                       zend_hash_del(ht, p->arKey, p->nKeyLength);
-                                                               } else {
-                                                                       zend_hash_index_del(ht, p->h);
-                                                               }
-                                                               return FAILURE;
-                                                       }
-                                               }
-                                       }
-                                       q = q->pNext;
+                       q = ht->arBuckets[num_index & ht->nTableMask];
+                       while (q != NULL) {
+                               if (!q->nKeyLength && q->h == num_index) {
+                                       break;
                                }
+                               q = q->pNext;
                        }
-
-                       zend_hash_index_del(ht, num_index);
                } else if (key_type == HASH_KEY_IS_STRING) {
+                       ulong h;
+
                        if (p->nKeyLength == str_length &&
                            memcmp(p->arKey, str_index, str_length) == 0) {
                                return SUCCESS;
                        }
 
-                       if (mode != HASH_UPDATE_KEY_ANYWAY) {
-                               ulong h = zend_inline_hash_func(str_index, str_length);
-                               Bucket *q = ht->arBuckets[h & ht->nTableMask];
-                               int found = 0;
-
-                               while (q != NULL) {
-                                       if (q == p) {
-                                               found = 1;
-                                       } else if (q->h == h && q->nKeyLength == str_length && 
-                                                  memcmp(q->arKey, str_index, str_length) == 0) {
-                                           if (found) {
-                                                       if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
-                                                               break;
-                                                       } else {
-                                                               if (p->nKeyLength) {
-                                                                       zend_hash_del(ht, p->arKey, p->nKeyLength);
-                                                               } else {
-                                                                       zend_hash_index_del(ht, p->h);
-                                                               }
-                                                               return FAILURE;
-                                                       }
-                                               } else {
-                                                       if (mode & HASH_UPDATE_KEY_IF_AFTER) {
-                                                               break;
-                                                       } else {
-                                                               if (p->nKeyLength) {
-                                                                       zend_hash_del(ht, p->arKey, p->nKeyLength);
-                                                               } else {
-                                                                       zend_hash_index_del(ht, p->h);
-                                                               }
-                                                               return FAILURE;
-                                                       }
-                                               }
-                                       }
-                                       q = q->pNext;
+                       h = zend_inline_hash_func(str_index, str_length);
+                       q = ht->arBuckets[h & ht->nTableMask];
+
+                       while (q != NULL) {
+                               if (q->h == h && q->nKeyLength == str_length && 
+                                          memcmp(q->arKey, str_index, str_length) == 0) {
+                                       break;
                                }
+                               q = q->pNext;
                        }
-
-                       zend_hash_del(ht, str_index, str_length);
                } else {
                        return FAILURE;
                }
 
                HANDLE_BLOCK_INTERRUPTIONS();
 
+               if (q) {
+                       if (mode != HASH_UPDATE_KEY_ANYWAY) {
+                               Bucket *r = p->pListLast;
+                               int found = HASH_UPDATE_KEY_IF_BEFORE;
+                                               
+                               while (r) {
+                                       if (r == q) {
+                                               found = HASH_UPDATE_KEY_IF_AFTER;
+                                               break;
+                                       }
+                                       r = r->pListLast;
+                               }
+                               if (mode & found) {
+                                       /* delete current bucket */
+                                       if (p == ht->arBuckets[p->h & ht->nTableMask]) {
+                                               ht->arBuckets[p->h & ht->nTableMask] = p->pNext;
+                                       } else {
+                                               p->pLast->pNext = p->pNext;
+                                       }
+                                       if (p->pNext) {
+                                               p->pNext->pLast = p->pLast;
+                                       }
+                                       if (p->pListLast != NULL) {
+                                               p->pListLast->pListNext = p->pListNext;
+                                       } else { 
+                                               /* Deleting the head of the list */
+                                               ht->pListHead = p->pListNext;
+                                       }
+                                       if (p->pListNext != NULL) {
+                                               p->pListNext->pListLast = p->pListLast;
+                                       } else {
+                                               ht->pListTail = p->pListLast;
+                                       }
+                                       if (ht->pInternalPointer == p) {
+                                               ht->pInternalPointer = p->pListNext;
+                                       }
+                                       if (ht->pDestructor) {
+                                               ht->pDestructor(p->pData);
+                                       }
+                                       if (p->pData != &p->pDataPtr) {
+                                               pefree(p->pData, ht->persistent);
+                                       }
+                                       pefree(p, ht->persistent);
+                                       ht->nNumOfElements--;
+                                       HANDLE_UNBLOCK_INTERRUPTIONS();
+                                       return FAILURE;
+                               }
+                       }
+                       /* delete another bucket with the same key */
+                       if (q == ht->arBuckets[q->h & ht->nTableMask]) {
+                               ht->arBuckets[q->h & ht->nTableMask] = q->pNext;
+                       } else {
+                               q->pLast->pNext = q->pNext;
+                       }
+                       if (q->pNext) {
+                               q->pNext->pLast = q->pLast;
+                       }
+                       if (q->pListLast != NULL) {
+                               q->pListLast->pListNext = q->pListNext;
+                       } else { 
+                               /* Deleting the head of the list */
+                               ht->pListHead = q->pListNext;
+                       }
+                       if (q->pListNext != NULL) {
+                               q->pListNext->pListLast = q->pListLast;
+                       } else {
+                               ht->pListTail = q->pListLast;
+                       }
+                       if (ht->pInternalPointer == q) {
+                               ht->pInternalPointer = q->pListNext;
+                       }
+                       if (ht->pDestructor) {
+                               ht->pDestructor(q->pData);
+                       }
+                       if (q->pData != &q->pDataPtr) {
+                               pefree(q->pData, ht->persistent);
+                       }
+                       pefree(q, ht->persistent);
+                       ht->nNumOfElements--;
+               }
+
                if (p->pNext) {
                        p->pNext->pLast = p->pLast;
                }
                if (p->pLast) {
                        p->pLast->pNext = p->pNext;
-               } else{
+               } else {
                        ht->arBuckets[p->h & ht->nTableMask] = p->pNext;
                }