]> granicus.if.org Git - php/commitdiff
Optimized ZEND_SIGNED_MULTIPLY_LONG() (Matt)
authorDmitry Stogov <dmitry@php.net>
Thu, 24 Jul 2008 13:46:48 +0000 (13:46 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 24 Jul 2008 13:46:48 +0000 (13:46 +0000)
Zend/zend_alloc.c
Zend/zend_multiply.h
Zend/zend_types.h

index d758b8bbf4ad87fcec8220ba45ec70860dcb5b9e..27e392ccc2124bb48851126f2653f8ae3f7740ab 100644 (file)
@@ -2402,6 +2402,19 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
         return res;
 }
 
+#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
+
+static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+{
+       zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
+
+       if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
+               zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+               return 0;
+       }
+       return (size_t) res;
+}
+
 #else
 
 static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) /* {{{ */
index 0fe9eeba20476080e017e005c69cc86a22522bd7..8f5f03d70eda6cde9733a0fec0db6f1cc827e53a 100644 (file)
        else (lval) = __tmpvar;                                                                                 \
 } while (0)
 
+#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {      \
+       zend_long64 __result = (zend_long64) (a) * (zend_long64) (b);   \
+       if (__result > LONG_MAX || __result < LONG_MIN) {                               \
+               (dval) = (double) __result;                                                                     \
+               (usedval) = 1;                                                                                          \
+       } else {                                                                                                                \
+               (lval) = (long) __result;                                                                       \
+               (usedval) = 0;                                                                                          \
+       }                                                                                                                               \
+} while (0)
+
 #else
 
 #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do {              \
index 66b328547b06bec2237fa2f860ff28efd4a1c3d7..9ea1c44f21c67761aae334046f0871ffb07621c5 100644 (file)
@@ -28,6 +28,20 @@ typedef unsigned int zend_uint;
 typedef unsigned long zend_ulong;
 typedef unsigned short zend_ushort;
 
+#define HAVE_ZEND_LONG64
+#ifdef ZEND_WIN32
+typedef __int64 zend_long64;
+typedef unsigned __int64 zend_ulong64;
+#elif SIZEOF_LONG_LONG_INT == 8
+typedef long long int zend_long64;
+typedef unsigned long long int zend_ulong64;
+#elif SIZEOF_LONG_LONG == 8
+typedef long long zend_long64;
+typedef unsigned long long zend_ulong64;
+#else
+# undef HAVE_ZEND_LONG64
+#endif
+
 #ifdef _WIN64
 typedef __int64 zend_intptr_t;
 typedef unsigned __int64 zend_uintptr_t;