From dbfc4a3c8266e6d85164d2a85c6fb327899938a9 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 17 Sep 2022 15:49:36 +0200 Subject: [PATCH] Fix build for compilers without __builtin_mul_overflow --- build/php.m4 | 21 +++++++++++++++++++++ configure.ac | 2 ++ main/reallocarray.c | 9 +++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/build/php.m4 b/build/php.m4 index 637b2a180160f..235b94753ac38 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -2567,6 +2567,27 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CTZLL], [ AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_CTZLL], [$have_builtin_ctzll], [Whether the compiler supports __builtin_ctzll]) ]) +dnl +dnl PHP_CHECK_BUILTIN_MUL_OVERFLOW +dnl +AC_DEFUN([PHP_CHECK_BUILTIN_MUL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_mul_overflow]) + + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[ + long tmpvar; + return __builtin_mul_overflow(3, 7, &tmpvar); + ]])], [ + have_builtin_mul_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_mul_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_MUL_OVERFLOW], + [$have_builtin_mul_overflow], [Whether the compiler supports __builtin_mul_overflow]) +]) + dnl dnl PHP_CHECK_BUILTIN_SMULL_OVERFLOW dnl diff --git a/configure.ac b/configure.ac index 44f6da3f7d1d5..902696007e6c0 100644 --- a/configure.ac +++ b/configure.ac @@ -494,6 +494,8 @@ dnl Check __builtin_ctzl PHP_CHECK_BUILTIN_CTZL dnl Check __builtin_ctzll PHP_CHECK_BUILTIN_CTZLL +dnl Check __builtin_mul_overflow +PHP_CHECK_BUILTIN_MUL_OVERFLOW dnl Check __builtin_smull_overflow PHP_CHECK_BUILTIN_SMULL_OVERFLOW dnl Check __builtin_smulll_overflow diff --git a/main/reallocarray.c b/main/reallocarray.c index 95500ebdd8591..e917e57b197c0 100644 --- a/main/reallocarray.c +++ b/main/reallocarray.c @@ -15,6 +15,7 @@ */ #include "php.h" +#include "stdint.h" #ifndef HAVE_REALLOCARRAY @@ -23,10 +24,14 @@ PHPAPI void* php_reallocarray(void *p, size_t nmb, size_t siz) { size_t r; -#ifndef _WIN32 +#ifdef _WIN32 + if (SizeTMult(nmb, siz, &r) != S_OK) { +#elif defined(PHP_HAVE_BUILTIN_MUL_OVERFLOW) if (__builtin_mul_overflow(nmb, siz, &r)) { #else - if (SizeTMult(nmb, siz, &r) != S_OK) { + if (SIZE_MAX / siz >= nmb) { + r = siz * nmb; + } else { #endif // EOVERFLOW may have been, arguably, more appropriate // but this is what other implementations set