]> granicus.if.org Git - php/commitdiff
Fixed bug #45877 (Array key '2147483647' left as string)
authorMatt Wilmas <mattwil@php.net>
Wed, 18 Mar 2009 01:06:30 +0000 (01:06 +0000)
committerMatt Wilmas <mattwil@php.net>
Wed, 18 Mar 2009 01:06:30 +0000 (01:06 +0000)
Zend/tests/bug45877.phpt [new file with mode: 0644]
Zend/zend.h
Zend/zend_hash.h
Zend/zend_operators.h

diff --git a/Zend/tests/bug45877.phpt b/Zend/tests/bug45877.phpt
new file mode 100644 (file)
index 0000000..b651c66
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Bug #45877 (Array key '2147483647' left as string)
+--FILE--
+<?php
+$keys = array(PHP_INT_MAX,
+       (string) PHP_INT_MAX,
+       (string) (-PHP_INT_MAX - 1),
+       -PHP_INT_MAX - 1,
+       (string) (PHP_INT_MAX + 1));
+
+var_dump(array_fill_keys($keys, 1));
+?>
+--EXPECTF--
+array(3) {
+  [%d7]=>
+  int(1)
+  [-%d8]=>
+  int(1)
+  [u"%d8"]=>
+  int(1)
+}
index 1ba3f5e0a80e164b4e4258ac5c6344a3f70f24e4..63e862b0dd72ac5be24ae1cb3485507ee3d33e78 100644 (file)
@@ -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)
index 614608c1a24703b9c0c75dbbede903a0e385c771..d72b482af3b83df703822d1b4bff15c0b01299c6 100644 (file)
@@ -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<end) {                                                                                                                               \
@@ -418,17 +419,16 @@ ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type,
                        tmp++;                                                                                                                                          \
                }                                                                                                                                                               \
                if (tmp==end && *tmp=='\0') { /* a numeric index */                                                             \
-                       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;                                                                                                            \
+                       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);                                                                                                                                            \
 }
@@ -441,9 +441,10 @@ ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type,
        }                                                                                                                                                                       \
        if ((*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<end) {                                                                                                                               \
@@ -453,17 +454,16 @@ ZEND_API int zend_u_symtable_update_current_key(HashTable *ht, zend_uchar type,
                        tmp++;                                                                                                                                          \
                }                                                                                                                                                               \
                if (tmp==end && *tmp==0) { /* a numeric index */                                                                \
-                       if (*key==0x2D /*'-'*/) {                                                                                                       \
-                               idx = zend_u_strtol(key, NULL, 10);                                                                             \
-                               if (idx!=LONG_MIN) {                                                                                                    \
-                                       return func;                                                                                                            \
-                               }                                                                                                                                               \
-                       } else {                                                                                                                                        \
-                               idx = zend_u_strtol(key, NULL, 10);                                                                             \
-                               if (idx!=LONG_MAX) {                                                                                                    \
-                                       return func;                                                                                                            \
+                       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);                                                                                                                                            \
 }
index 5411f46ec78b7061f5846d6c435509c32edb813e..0457e2ac371807e45523e4227ebbb51f95f64d5f 100644 (file)
 #include "ext/bcmath/libbcmath/src/bcmath.h"
 #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
-
 BEGIN_EXTERN_C()
 ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
 ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);