diff options
author | Dmitry Stogov <dmitry@php.net> | 2009-03-18 09:48:55 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2009-03-18 09:48:55 +0000 |
commit | d3b42700a0279bfcd58414799b81cd332d1fa08f (patch) | |
tree | a329e13dc13ff0619c4c536927307ff906e6a459 /Zend/zend_hash.h | |
parent | 408abe99a7cdb4ffd07fd82ff78dd4c3c99254c9 (diff) | |
download | php-git-d3b42700a0279bfcd58414799b81cd332d1fa08f.tar.gz |
Better fix for bug #45877 (smaller and faster)
Diffstat (limited to 'Zend/zend_hash.h')
-rw-r--r-- | Zend/zend_hash.h | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 698fe4a548..b63c084a56 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -304,42 +304,37 @@ END_EXTERN_C() #define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \ zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent) - -#define ZEND_HANDLE_NUMERIC(key, length, func) { \ - register const char *tmp=key; \ - \ - if (*tmp=='-') { \ - tmp++; \ - } \ - if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \ - const char *end=key+length-1; \ - long idx = end - tmp; /* temp var for remaining length (number of digits) */ \ - \ - if (idx > MAX_LENGTH_OF_LONG - 1 || (*tmp++ == '0' && length > 2)) { \ - /* don't accept numbers too long or with leading zeros */ \ - break; \ - } \ - while (tmp<end) { \ - if (!(*tmp>='0' && *tmp<='9')) { \ - break; \ - } \ - tmp++; \ - } \ - if (tmp==end && *tmp=='\0') { /* a numeric index */ \ - if (idx == MAX_LENGTH_OF_LONG - 1) { \ - int cmp = strcmp(end - (MAX_LENGTH_OF_LONG - 1), long_min_digits); \ - \ - if (!(cmp < 0 || (cmp == 0 && *key == '-'))) { \ - break; \ - } \ - } \ - \ - idx = strtol(key, NULL, 10); \ - return func; \ - } \ - } while (0); \ -} - +#define ZEND_HANDLE_NUMERIC(key, length, func) do { \ + register const char *tmp = key; \ + const char *end = key + length - 1; \ + long idx; \ + \ + if (*tmp == '-') { \ + tmp++; \ + } \ + if ((*tmp >= '1' && *tmp <= '9' && (end - tmp) < MAX_LENGTH_OF_LONG) || \ + (*tmp == '0' && (end - tmp) == 1)) { \ + /* possibly a numeric index without leading zeroes */ \ + idx = (*tmp++ - '0'); \ + while (1) { \ + if (tmp == end && *tmp == '\0') { /* a numeric index */ \ + if (*key == '-') { \ + idx = -idx; \ + if (idx > 0) { /* overflow */ \ + break; \ + } \ + } else if (idx < 0) { /* overflow */ \ + break; \ + } \ + return func; \ + } else if (*tmp >= '0' && *tmp <= '9') { \ + idx = (idx * 10) + (*tmp++ - '0'); \ + } else { \ + break; \ + } \ + } \ + } \ +} while (0) static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \ { @@ -350,7 +345,7 @@ static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nK static inline int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength) { - ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx)) + ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx)); return zend_hash_del(ht, arKey, nKeyLength); } |