]> granicus.if.org Git - php/commitdiff
Better fix for bug #45877 (smaller and faster)
authorDmitry Stogov <dmitry@php.net>
Wed, 18 Mar 2009 09:49:07 +0000 (09:49 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 18 Mar 2009 09:49:07 +0000 (09:49 +0000)
Zend/zend_hash.c
Zend/zend_hash.h

index aaa075626c990ebfc05e29e110bdc2ab3bc5c377..ea690e9ed2e6f3395b9ea931affdde0f76036c1a 100644 (file)
@@ -2071,7 +2071,7 @@ ZEND_API int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLen
 
 ZEND_API 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);
 }
 /* }}} */
@@ -2106,7 +2106,7 @@ ZEND_API int zend_ascii_symtable_update(HashTable *ht, const char *arKey, uint n
 
 ZEND_API int zend_ascii_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_ascii_hash_del(ht, arKey, nKeyLength);
 }
 /* }}} */
@@ -2134,7 +2134,7 @@ ZEND_API int zend_rt_symtable_update(HashTable *ht, const char *arKey, uint nKey
 
 ZEND_API int zend_rt_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_rt_hash_del(ht, arKey, nKeyLength);
 }
 /* }}} */
@@ -2162,7 +2162,7 @@ ZEND_API int zend_utf8_symtable_update(HashTable *ht, const char *arKey, uint nK
 
 ZEND_API int zend_utf8_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_utf8_hash_del(ht, arKey, nKeyLength);
 }
 /* }}} */
index d72b482af3b83df703822d1b4bff15c0b01299c6..eb3a479b34b2fb2243f2a397823ea12d3fe7500f 100644 (file)
@@ -398,75 +398,69 @@ ZEND_API int zend_u_symtable_exists(HashTable *ht, zend_uchar type, zstr arKey,
 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) {                                                                               \
-       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_U_NUMERIC(key, length, func) {                                                                             \
-       register UChar *tmp=key;                                                                                                                        \
-                                                                                                                                                                               \
-       if (*tmp==0x2D /*'-'*/) {                                                                                                                       \
-               tmp++;                                                                                                                                                  \
-       }                                                                                                                                                                       \
-       if ((*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) do { /* possibly a numeric index */     \
-               UChar *end=key+length-1;                                                                                                                \
-               long idx = end - tmp; /* temp var for remaining length (number of digits) */    \
-                                                                                                                                                                               \
-               if (idx > MAX_LENGTH_OF_LONG - 1 || (*tmp++ == 0x30 && length > 2)) {                   \
-                       /* don't accept numbers too long or with leading zeros */                                                               \
-                       break;                                                                                                                                          \
-               }                                                                                                                                                               \
-               while (tmp<end) {                                                                                                                               \
-                       if (!(*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) {                                                      \
-                               break;                                                                                                                                  \
-                       }                                                                                                                                                       \
-                       tmp++;                                                                                                                                          \
-               }                                                                                                                                                               \
-               if (tmp==end && *tmp==0) { /* a numeric index */                                                                \
-                       if (idx == MAX_LENGTH_OF_LONG - 1) {                                                                            \
-                               int cmp = zend_cmp_unicode_and_literal(end - (MAX_LENGTH_OF_LONG - 1), idx, long_min_digits, idx);      \
-                                                                                                                                                                               \
-                               if (!(cmp < 0 || (cmp == 0 && *key == 0x2D /*'-'*/))) {                                 \
-                                       break;                                                                                                                          \
-                               }                                                                                                                                               \
-                       }                                                                                                                                                       \
-                                                                                                                                                                               \
-                       idx = zend_u_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)
+
+#define ZEND_HANDLE_U_NUMERIC(key, length, func) do {                                          \
+       register const UChar *tmp = key;                                                                                \
+       const UChar *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)
 /* }}} */
 
 #endif                                                 /* ZEND_HASH_H */