cvs: ZendEngine2(PHP_5_3) / zend_execute_API.c zend_hash.c zend_hash.h /tests bug28072.phpt php-src NEWS

"Dmitry Stogov" <[email protected]>
Newsgroups gmane.comp.php.cvs.zend
Message-ID <cvsdmitry1217600523@cvsserver>
dmitry		Fri Aug  1 14:22:03 2008 UTC

  Modified files:              (Branch: PHP_5_3)
    /php-src	NEWS 
    /ZendEngine2	zend_execute_API.c zend_hash.c zend_hash.h 
    /ZendEngine2/tests	bug28072.phpt 
  Log:
  Fixed bug #44100 (Inconsistent handling of static array declarations with duplicate keys).

-- 
Zend Engine CVS Mailing List (http://cvs.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
dmitry-20080801142203.txt (text/plain, 9.3 KB)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.239&r2=1.2027.2.547.2.965.2.240&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.965.2.239 php-src/NEWS:1.2027.2.547.2.965.2.240
--- php-src/NEWS:1.2027.2.547.2.965.2.239	Fri Aug  1 00:46:20 2008
+++ php-src/NEWS	Fri Aug  1 14:22:02 2008
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 200?, PHP 5.3.0 Alpha 2
+- Fixed bug #44100 (Inconsistent handling of static array declarations with
+  duplicate keys). (Dmitry)
 
 01 Aug 2008, PHP 5.3.0 Alpha 1
 - Upgraded bundled PCRE to version 7.7 (Nuno)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute_API.c?r1=1.331.2.20.2.24.2.49&r2=1.331.2.20.2.24.2.50&diff_format=u
Index: ZendEngine2/zend_execute_API.c
diff -u ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.49 ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.50
--- ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.49	Sat Jul 26 19:14:38 2008
+++ ZendEngine2/zend_execute_API.c	Fri Aug  1 14:22:03 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_execute_API.c,v 1.331.2.20.2.24.2.49 2008/07/26 19:14:38 dmitry Exp $ */
+/* $Id: zend_execute_API.c,v 1.331.2.20.2.24.2.50 2008/08/01 14:22:03 dmitry Exp $ */
 
 #include <stdio.h>
 #include <signal.h>
@@ -599,17 +599,17 @@
 
 			switch (Z_TYPE(const_value)) {
 				case IS_STRING:
-					zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1);
+					zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
 					break;
 				case IS_BOOL:
 				case IS_LONG:
-					zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value));
+					zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
 					break;
 				case IS_DOUBLE:
-					zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, (long)Z_DVAL(const_value));
+					zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, (long)Z_DVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
 					break;
 				case IS_NULL:
-					zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0);
+					zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
 					break;
 			}
 			zend_hash_move_forward(Z_ARRVAL_P(p));
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_hash.c?r1=1.121.2.4.2.8.2.3&r2=1.121.2.4.2.8.2.4&diff_format=u
Index: ZendEngine2/zend_hash.c
diff -u ZendEngine2/zend_hash.c:1.121.2.4.2.8.2.3 ZendEngine2/zend_hash.c:1.121.2.4.2.8.2.4
--- ZendEngine2/zend_hash.c:1.121.2.4.2.8.2.3	Thu Jul 24 19:52:23 2008
+++ ZendEngine2/zend_hash.c	Fri Aug  1 14:22:03 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_hash.c,v 1.121.2.4.2.8.2.3 2008/07/24 19:52:23 felipe Exp $ */
+/* $Id: zend_hash.c,v 1.121.2.4.2.8.2.4 2008/08/01 14:22:03 dmitry Exp $ */
 
 #include "zend.h"
 
@@ -1170,7 +1170,7 @@
 /* This function changes key of currevt element without changing elements'
  * order. If element with target key already exists, it will be deleted first.
  */
-ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, HashPosition *pos)
+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;
 
@@ -1184,12 +1184,72 @@
 			if (!p->nKeyLength && p->h == num_index) {
 				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 {
+								zend_hash_index_del(ht, p->h);
+					    		return FAILURE;
+					    	}
+					    } else {
+					    	if (mode & HASH_UPDATE_KEY_IF_AFTER) {
+					    		break;
+					    	} else {
+								zend_hash_index_del(ht, p->h);
+					    		return FAILURE;
+					    	}
+						}
+					}
+					q = q->pNext;
+				}
+			}
+
 			zend_hash_index_del(ht, num_index);
 		} else if (key_type == HASH_KEY_IS_STRING) {
 			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 {
+								zend_hash_del(ht, p->arKey, p->nKeyLength);
+					    		return FAILURE;
+					    	}
+					    } else {
+					    	if (mode & HASH_UPDATE_KEY_IF_AFTER) {
+					    		break;
+					    	} else {
+								zend_hash_del(ht, p->arKey, p->nKeyLength);
+					    		return FAILURE;
+					    	}
+						}
+					}
+					q = q->pNext;
+				}
+			}
+
 			zend_hash_del(ht, str_index, str_length);
 		} else {
 			return FAILURE;
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_hash.h?r1=1.78.2.2.2.2.2.5&r2=1.78.2.2.2.2.2.6&diff_format=u
Index: ZendEngine2/zend_hash.h
diff -u ZendEngine2/zend_hash.h:1.78.2.2.2.2.2.5 ZendEngine2/zend_hash.h:1.78.2.2.2.2.2.6
--- ZendEngine2/zend_hash.h:1.78.2.2.2.2.2.5	Thu Jul 24 19:52:23 2008
+++ ZendEngine2/zend_hash.h	Fri Aug  1 14:22:03 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_hash.h,v 1.78.2.2.2.2.2.5 2008/07/24 19:52:23 felipe Exp $ */
+/* $Id: zend_hash.h,v 1.78.2.2.2.2.2.6 2008/08/01 14:22:03 dmitry Exp $ */
 
 #ifndef ZEND_HASH_H
 #define ZEND_HASH_H
@@ -37,6 +37,11 @@
 #define HASH_DEL_INDEX 1
 #define HASH_DEL_KEY_QUICK 2
 
+#define HASH_UPDATE_KEY_IF_NONE    0
+#define HASH_UPDATE_KEY_IF_BEFORE  1
+#define HASH_UPDATE_KEY_IF_AFTER   2
+#define HASH_UPDATE_KEY_ANYWAY     3
+
 typedef ulong (*hash_func_t)(const char *arKey, uint nKeyLength);
 typedef int  (*compare_func_t)(const void *, const void * TSRMLS_DC);
 typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
@@ -124,7 +129,6 @@
 #define ZEND_HASH_APPLY_REMOVE				1<<0
 #define ZEND_HASH_APPLY_STOP				1<<1
 
-
 typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
 typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
 typedef int (*apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
@@ -177,7 +181,7 @@
 ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
 ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
 ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
-ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, HashPosition *pos);
+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);
 
 typedef struct _HashPointer {
 	HashPosition pos;
@@ -204,7 +208,7 @@
 #define zend_hash_internal_pointer_end(ht) \
 	zend_hash_internal_pointer_end_ex(ht, NULL)
 #define zend_hash_update_current_key(ht, key_type, str_index, str_length, num_index) \
-	zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, NULL)
+	zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
 
 /* Copying, merging and sorting */
 ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
@@ -364,10 +368,10 @@
 	return zend_hash_exists(ht, arKey, nKeyLength);
 }
 
-static inline int zend_symtable_update_current_key(HashTable *ht, const char *arKey, uint nKeyLength)
+static inline int zend_symtable_update_current_key(HashTable *ht, const char *arKey, uint nKeyLength, int mode)
 {
-	ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key(ht, HASH_KEY_IS_LONG, NULL, 0, idx));
-	return zend_hash_update_current_key(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0);
+	ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, 0, idx, mode, NULL));
+	return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0, mode, NULL);
 }
 
 #endif							/* ZEND_HASH_H */
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug28072.phpt?r1=1.1&r2=1.1.6.1&diff_format=u
Index: ZendEngine2/tests/bug28072.phpt
diff -u ZendEngine2/tests/bug28072.phpt:1.1 ZendEngine2/tests/bug28072.phpt:1.1.6.1
--- ZendEngine2/tests/bug28072.phpt:1.1	Thu Jul  7 15:16:57 2005
+++ ZendEngine2/tests/bug28072.phpt	Fri Aug  1 14:22:03 2008
@@ -41,6 +41,6 @@
 )
 Array
 (
-    [a] => 111
+    [a] => 222
     [c] => 444
 )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.