diff options
author | Dmitry Stogov <dmitry@php.net> | 2009-03-19 15:16:10 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2009-03-19 15:16:10 +0000 |
commit | 9f32cb2d39e435d1857a35be918a417acbeb23cc (patch) | |
tree | d35a3efcdc14fc8a493d89534c08056cbc680639 | |
parent | 8623e9db8b1b774c6c7ec96832f34513521ea0fa (diff) | |
download | php-git-9f32cb2d39e435d1857a35be918a417acbeb23cc.tar.gz |
Fixed check for long integer overflow
-rw-r--r-- | Zend/zend_hash.h | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index b63c084a56..793f85e865 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -306,18 +306,42 @@ END_EXTERN_C() #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 (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */ \ + const char *end = key + length - 1; \ + long idx; \ + \ + if (*end != '\0') { /* not a null terminated string */ \ + break; \ + } else if (*tmp == '0') { \ + if (end - tmp != 1) { \ + /* don't accept numbers with leading zeros */ \ + break; \ + } \ + idx = 0; \ + } else if (end - tmp > MAX_LENGTH_OF_LONG - 1) { \ + /* don't accept too long strings */ \ + break; \ + } else { \ + if (end - tmp == MAX_LENGTH_OF_LONG - 1) { \ + end--; /* check overflow in last digit later */ \ + } \ + idx = (*tmp++ - '0'); \ + while (tmp != end && *tmp >= '0' && *tmp <= '9') { \ + idx = (idx * 10) + (*tmp++ - '0'); \ + } \ + if (tmp != end) { \ + break; \ + } \ + if (end != key + length - 1) { \ + /* last digit can cause overflow */ \ + if (*tmp < '0' || *tmp > '9' || idx > LONG_MAX / 10) { \ + break; \ + } \ + idx = (idx * 10) + (*tmp - '0'); \ if (*key == '-') { \ idx = -idx; \ if (idx > 0) { /* overflow */ \ @@ -326,13 +350,11 @@ END_EXTERN_C() } else if (idx < 0) { /* overflow */ \ break; \ } \ - return func; \ - } else if (*tmp >= '0' && *tmp <= '9') { \ - idx = (idx * 10) + (*tmp++ - '0'); \ - } else { \ - break; \ + } else if (*key == '-') { \ + idx = -idx; \ } \ } \ + return func; \ } \ } while (0) |