cvs: ZendEngine2 / zend_execute_API.c zend_hash.c zend_hash.h /tests bug28072.phpt
"Dmitry Stogov" <[email protected]>
| Newsgroups | gmane.comp.php.cvs.zend |
|---|---|
| Message-ID | <cvsdmitry1217600506@cvsserver> |
dmitry Fri Aug 1 14:21:46 2008 UTC
Modified files:
/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-20080801142146.txt
(text/plain, 11.3 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute_API.c?r1=1.455&r2=1.456&diff_format=u
Index: ZendEngine2/zend_execute_API.c
diff -u ZendEngine2/zend_execute_API.c:1.455 ZendEngine2/zend_execute_API.c:1.456
--- ZendEngine2/zend_execute_API.c:1.455 Sat Jul 26 17:01:59 2008
+++ ZendEngine2/zend_execute_API.c Fri Aug 1 14:21:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_execute_API.c,v 1.455 2008/07/26 17:01:59 dmitry Exp $ */
+/* $Id: zend_execute_API.c,v 1.456 2008/08/01 14:21:45 dmitry Exp $ */
#include <stdio.h>
#include <signal.h>
@@ -654,17 +654,17 @@
switch (Z_TYPE(const_value)) {
case IS_STRING:
case IS_UNICODE:
- zend_u_symtable_update_current_key(Z_ARRVAL_P(p), Z_TYPE(const_value), Z_UNIVAL(const_value), Z_UNILEN(const_value) + 1);
+ zend_u_symtable_update_current_key(Z_ARRVAL_P(p), Z_TYPE(const_value), Z_UNIVAL(const_value), Z_UNILEN(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_ZSTR, 0, Z_LVAL(const_value));
+ zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 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_ZSTR, 0, (long)Z_DVAL(const_value));
+ zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL_ZSTR, 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, EMPTY_ZSTR, 1, 0);
+ zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, EMPTY_ZSTR, 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.156&r2=1.157&diff_format=u
Index: ZendEngine2/zend_hash.c
diff -u ZendEngine2/zend_hash.c:1.156 ZendEngine2/zend_hash.c:1.157
--- ZendEngine2/zend_hash.c:1.156 Thu Jul 24 19:50:22 2008
+++ ZendEngine2/zend_hash.c Fri Aug 1 14:21:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_hash.c,v 1.156 2008/07/24 19:50:22 felipe Exp $ */
+/* $Id: zend_hash.c,v 1.157 2008/08/01 14:21:45 dmitry Exp $ */
#include "zend.h"
#include "zend_operators.h"
@@ -1646,7 +1646,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, zstr str_index, uint str_length, ulong num_index, HashPosition *pos) /* {{{ */
+ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, zstr str_index, uint str_length, ulong num_index, int mode, HashPosition *pos) /* {{{ */
{
Bucket *p;
uint real_length;
@@ -1661,23 +1661,77 @@
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) {
- real_length = str_length;
+ } else if (key_type == HASH_KEY_IS_STRING ||
+ key_type == HASH_KEY_IS_UNICODE) {
+ real_length = key_type == HASH_KEY_IS_STRING ? str_length : str_length * sizeof(UChar);
if (p->nKeyLength == str_length &&
- p->key.type == IS_STRING &&
- memcmp(p->key.arKey.s, str_index.s, str_length) == 0) {
+ p->key.type == key_type &&
+ memcmp(p->key.arKey.s, str_index.v, real_length) == 0) {
return SUCCESS;
}
- zend_u_hash_del(ht, IS_STRING, str_index, str_length);
- } else if (key_type == HASH_KEY_IS_UNICODE) {
- real_length = str_length * sizeof(UChar);
- if (p->nKeyLength == str_length &&
- p->key.type == IS_UNICODE &&
- memcmp(p->key.arKey.u, str_index.u, real_length) == 0) {
- return SUCCESS;
+
+ if (mode != HASH_UPDATE_KEY_ANYWAY) {
+ ulong h = zend_u_inline_hash_func(key_type, 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 &&
+ q->key.type == key_type &&
+ memcmp(q->key.arKey.s, str_index.v, real_length) == 0) {
+ if (found) {
+ if (mode & HASH_UPDATE_KEY_IF_BEFORE) {
+ break;
+ } else {
+ zend_u_hash_del(ht, p->key.type, ZSTR(p->key.arKey.s), p->nKeyLength);
+ return FAILURE;
+ }
+ } else {
+ if (mode & HASH_UPDATE_KEY_IF_AFTER) {
+ break;
+ } else {
+ zend_u_hash_del(ht, p->key.type, ZSTR(p->key.arKey.s), p->nKeyLength);
+ return FAILURE;
+ }
+ }
+ }
+ q = q->pNext;
+ }
}
- zend_u_hash_del(ht, IS_UNICODE, str_index, str_length);
+
+ zend_u_hash_del(ht, key_type, str_index, str_length);
} else {
return FAILURE;
}
@@ -1977,18 +2031,18 @@
}
/* }}} */
-ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength) /* {{{ */
+ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, int mode) /* {{{ */
{
zend_uchar key_type;
if (type == IS_STRING) {
key_type = HASH_KEY_IS_STRING;
- ZEND_HANDLE_NUMERIC(arKey.s, nKeyLength, zend_hash_update_current_key(ht, HASH_KEY_IS_LONG, NULL_ZSTR, 0, idx));
+ ZEND_HANDLE_NUMERIC(arKey.s, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL_ZSTR, 0, idx, mode, NULL));
} else {
key_type = HASH_KEY_IS_UNICODE;
- ZEND_HANDLE_U_NUMERIC(arKey.u, nKeyLength, zend_hash_update_current_key(ht, HASH_KEY_IS_LONG, NULL_ZSTR, 0, idx));
+ ZEND_HANDLE_U_NUMERIC(arKey.u, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL_ZSTR, 0, idx, mode, NULL));
}
- return zend_hash_update_current_key(ht, key_type, arKey, nKeyLength, 0);
+ return zend_hash_update_current_key_ex(ht, key_type, arKey, nKeyLength, 0, mode, NULL);
}
/* }}} */
@@ -2020,10 +2074,10 @@
}
/* }}} */
-ZEND_API int zend_symtable_update_current_key(HashTable *ht, const char *arKey, uint nKeyLength) /* {{{ */
+ZEND_API 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_ZSTR, 0, idx));
- return zend_hash_update_current_key(ht, HASH_KEY_IS_STRING, ZSTR(arKey), nKeyLength, 0);
+ ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL_ZSTR, 0, idx, mode, NULL));
+ return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, ZSTR(arKey), nKeyLength, 0, mode, NULL);
}
/* }}} */
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_hash.h?r1=1.95&r2=1.96&diff_format=u
Index: ZendEngine2/zend_hash.h
diff -u ZendEngine2/zend_hash.h:1.95 ZendEngine2/zend_hash.h:1.96
--- ZendEngine2/zend_hash.h:1.95 Thu Jul 24 19:50:22 2008
+++ ZendEngine2/zend_hash.h Fri Aug 1 14:21:45 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_hash.h,v 1.95 2008/07/24 19:50:22 felipe Exp $ */
+/* $Id: zend_hash.h,v 1.96 2008/08/01 14:21:45 dmitry Exp $ */
#ifndef ZEND_HASH_H
#define ZEND_HASH_H
@@ -38,7 +38,10 @@
#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);
@@ -240,7 +243,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, zstr str_index, uint str_length, ulong num_index, HashPosition *pos);
+ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, zstr str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
typedef struct _HashPointer {
HashPosition pos;
@@ -267,7 +270,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);
@@ -371,7 +374,7 @@
ZEND_API int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
ZEND_API int zend_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength);
-ZEND_API int zend_symtable_update_current_key(HashTable *ht, const char *arKey, uint nKeyLength);
+ZEND_API int zend_symtable_update_current_key(HashTable *ht, const char *arKey, uint nKeyLength, int mode);
ZEND_API int zend_ascii_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
ZEND_API int zend_ascii_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength);
@@ -392,7 +395,7 @@
ZEND_API int zend_u_symtable_del(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
ZEND_API int zend_u_symtable_find(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, void **pData);
ZEND_API int zend_u_symtable_exists(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
-ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength);
+ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type, zstr arKey, uint nKeyLength, int mode);
/* {{{ ZEND_HANDLE_*_NUMERIC macros */
#define ZEND_HANDLE_NUMERIC(key, length, func) { \
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug28072.phpt?r1=1.1&r2=1.2&diff_format=u
Index: ZendEngine2/tests/bug28072.phpt
diff -u ZendEngine2/tests/bug28072.phpt:1.1 ZendEngine2/tests/bug28072.phpt:1.2
--- ZendEngine2/tests/bug28072.phpt:1.1 Thu Jul 7 15:16:57 2005
+++ ZendEngine2/tests/bug28072.phpt Fri Aug 1 14:21:46 2008
@@ -41,6 +41,6 @@
)
Array
(
- [a] => 111
+ [a] => 222
[c] => 444
)