Re: Bugfix #21918
| From: | (Marcus B�rger) | Date: | Mon, 11 Aug 2003 01:49:15 +0000 |
| Subject: | Re: Bugfix #21918 | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-3852@lists.php.net to get a copy of this message | ||
Hello Marcus,
Monday, August 11, 2003, 3:31:54 AM, you wrote:
MB> Hello internals,
MB> according to our manual index values are either strings or integers. In case
MB> of strings which represent integers they are also handled as integers. Bug
MB> 21918 now shows that this currently only works for zero and positive index
MB> values. The attached patch would fix this.
Ilia just reminded me of some update problems with negative index values. To fix
those to i've put together another patch as attached. Now the following works, too:
php -r ' $arr[-6] = "me"; $arr[] = "you"; var_dump($arr); '
array(2) {
[-6]=>
string(2) "me"
[-5]=>
string(3) "you"
}
--
Best regards,
Marcus mailto:helly@php.net
Index: Zend/zend_hash.h =================================================================== RCS file: /repository/ZendEngine2/zend_hash.h,v retrieving revision 1.72 diff -u -p -d -r1.72 zend_hash.h --- Zend/zend_hash.h 23 Jul 2003 08:56:34 -0000 1.72 +++ Zend/zend_hash.h 11 Aug 2003 01:47:12 -0000 @@ -287,8 +287,11 @@ END_EXTERN_C() #define HANDLE_NUMERIC(key, length, func) { \ register char *tmp=key; \ \ + if (*tmp=='-') { \ + tmp++; \ + } \ if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \ - char *end=tmp+length-1; \ + char *end=key+length-1; \ ulong idx; \ \ if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \ @@ -301,9 +304,16 @@ END_EXTERN_C() tmp++; \ } \ if (tmp==end && *tmp=='\0') { /* a numeric index */ \ - idx = strtol(key, NULL, 10); \ - if (idx!=LONG_MAX) { \ - return func; \ + if (*key=='-') { \ + idx = strtol(key, NULL, 10); \ + if (idx!=LONG_MIN) { \ + return func; \ + } \ + } else { \ + idx = strtol(key, NULL, 10); \ + if (idx!=LONG_MAX) { \ + return func; \ + } \ } \ } \ } while (0); \ Index: Zend/zend_hash.c =================================================================== RCS file: /repository/ZendEngine2/zend_hash.c,v retrieving revision 1.109 diff -u -p -d -r1.109 zend_hash.c --- Zend/zend_hash.c 31 Jul 2003 05:08:59 -0000 1.109 +++ Zend/zend_hash.c 11 Aug 2003 01:47:12 -0000 @@ -364,7 +364,7 @@ ZEND_API int zend_hash_index_update_or_n } UPDATE_DATA(ht, p, pData, nDataSize); HANDLE_UNBLOCK_INTERRUPTIONS(); - if ((long)h >= (long)ht->nNextFreeElement) { + if ((long)h >= (long)ht->nNextFreeElement || !ht->nNumOfElements) { ht->nNextFreeElement = h + 1; } if (pDest) { @@ -392,7 +392,7 @@ ZEND_API int zend_hash_index_update_or_n CONNECT_TO_GLOBAL_DLLIST(p, ht); HANDLE_UNBLOCK_INTERRUPTIONS(); - if ((long)h >= (long)ht->nNextFreeElement) { + if ((long)h >= (long)ht->nNextFreeElement || !ht->nNumOfElements) { ht->nNextFreeElement = h + 1; } ht->nNumOfElements++;
Index: Zend/zend_hash.h =================================================================== RCS file: /repository/ZendEngine2/zend_hash.h,v retrieving revision 1.72 diff -u -p -d -r1.72 zend_hash.h --- Zend/zend_hash.h 23 Jul 2003 08:56:34 -0000 1.72 +++ Zend/zend_hash.h 11 Aug 2003 01:47:12 -0000 @@ -287,8 +287,11 @@ END_EXTERN_C() #define HANDLE_NUMERIC(key, length, func) { \ register char *tmp=key; \ \ + if (*tmp=='-') { \ + tmp++; \ + } \ if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \ - char *end=tmp+length-1; \ + char *end=key+length-1; \ ulong idx; \ \ if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \ @@ -301,9 +304,16 @@ END_EXTERN_C() tmp++; \ } \ if (tmp==end && *tmp=='\0') { /* a numeric index */ \ - idx = strtol(key, NULL, 10); \ - if (idx!=LONG_MAX) { \ - return func; \ + if (*key=='-') { \ + idx = strtol(key, NULL, 10); \ + if (idx!=LONG_MIN) { \ + return func; \ + } \ + } else { \ + idx = strtol(key, NULL, 10); \ + if (idx!=LONG_MAX) { \ + return func; \ + } \ } \ } \ } while (0); \ Index: Zend/zend_hash.c =================================================================== RCS file: /repository/ZendEngine2/zend_hash.c,v retrieving revision 1.109 diff -u -p -d -r1.109 zend_hash.c --- Zend/zend_hash.c 31 Jul 2003 05:08:59 -0000 1.109 +++ Zend/zend_hash.c 11 Aug 2003 01:47:12 -0000 @@ -364,7 +364,7 @@ ZEND_API int zend_hash_index_update_or_n } UPDATE_DATA(ht, p, pData, nDataSize); HANDLE_UNBLOCK_INTERRUPTIONS(); - if ((long)h >= (long)ht->nNextFreeElement) { + if ((long)h >= (long)ht->nNextFreeElement || !ht->nNumOfElements) { ht->nNextFreeElement = h + 1; } if (pDest) { @@ -392,7 +392,7 @@ ZEND_API int zend_hash_index_update_or_n CONNECT_TO_GLOBAL_DLLIST(p, ht); HANDLE_UNBLOCK_INTERRUPTIONS(); - if ((long)h >= (long)ht->nNextFreeElement) { + if ((long)h >= (long)ht->nNextFreeElement || !ht->nNumOfElements) { ht->nNextFreeElement = h + 1; } ht->nNumOfElements++;