From d4207fc58d772a4424762029ed871e0147d84a03 Mon Sep 17 00:00:00 2001 From: Matt Wilmas Date: Wed, 18 Mar 2009 01:06:30 +0000 Subject: [PATCH] Fixed bug #45877 (Array key '2147483647' left as string) --- Zend/tests/bug45877.phpt | 21 +++++++++++++++++++ Zend/zend.h | 12 +++++++++++ Zend/zend_hash.h | 44 ++++++++++++++++++++-------------------- Zend/zend_operators.h | 12 ----------- 4 files changed, 55 insertions(+), 34 deletions(-) create mode 100644 Zend/tests/bug45877.phpt diff --git a/Zend/tests/bug45877.phpt b/Zend/tests/bug45877.phpt new file mode 100644 index 0000000000..b651c6639e --- /dev/null +++ b/Zend/tests/bug45877.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #45877 (Array key '2147483647' left as string) +--FILE-- + +--EXPECTF-- +array(3) { + [%d7]=> + int(1) + [-%d8]=> + int(1) + [u"%d8"]=> + int(1) +} diff --git a/Zend/zend.h b/Zend/zend.h index 1ba3f5e0a8..63e862b0dd 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -271,6 +271,18 @@ typedef union _zstr { #define LONG_MIN (- LONG_MAX - 1) #endif +#if SIZEOF_LONG == 4 +#define MAX_LENGTH_OF_LONG 11 +static const char long_min_digits[] = "2147483648"; +#elif SIZEOF_LONG == 8 +#define MAX_LENGTH_OF_LONG 20 +static const char long_min_digits[] = "9223372036854775808"; +#else +#error "Unknown SIZEOF_LONG" +#endif + +#define MAX_LENGTH_OF_DOUBLE 32 + #ifdef __GNUC__ # define ZSTR(x) ((zstr)((void*)(x))) # define NULL_ZSTR ZSTR((void*)NULL) diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 614608c1a2..d72b482af3 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -406,9 +406,10 @@ ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type, } \ if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \ const char *end=key+length-1; \ - long idx; \ + long idx = end - tmp; /* temp var for remaining length (number of digits) */ \ \ - if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \ + if (idx > MAX_LENGTH_OF_LONG - 1 || (*tmp++ == '0' && length > 2)) { \ + /* don't accept numbers too long or with leading zeros */ \ break; \ } \ while (tmp=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) do { /* possibly a numeric index */ \ UChar *end=key+length-1; \ - long idx; \ + long idx = end - tmp; /* temp var for remaining length (number of digits) */ \ \ - if (*tmp++==0x30 && length>2) { /* don't accept numbers with leading zeros */ \ + if (idx > MAX_LENGTH_OF_LONG - 1 || (*tmp++ == 0x30 && length > 2)) { \ + /* don't accept numbers too long or with leading zeros */ \ break; \ } \ while (tmp