diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index a7c322b1d8169..6a36086739730 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -22,6 +22,7 @@ extern "C" { #include } +#include "../intl_cppshims.h" #include "../intl_convertcpp.h" #include "../intl_common.h" @@ -138,7 +139,10 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRuleStatusVec) ZEND_ASSERT(BREAKITER_ERROR_CODE(bio) == U_BUFFER_OVERFLOW_ERROR); BREAKITER_ERROR_CODE(bio) = U_ZERO_ERROR; - std::unique_ptr rules = std::unique_ptr(new int32_t[num_rules]); + int32_t *r = zend_mm_safe_alloc(static_cast(num_rules), sizeof(int32_t)); + + std::unique_ptr)> rules(r, zend_mm_destructor); + num_rules = fetch_rbbi(bio)->getRuleStatusVec(rules.get(), num_rules, BREAKITER_ERROR_CODE(bio)); if (U_FAILURE(BREAKITER_ERROR_CODE(bio))) { diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h index 169448a2edf33..faedc6fb8623f 100644 --- a/ext/intl/intl_cppshims.h +++ b/ext/intl/intl_cppshims.h @@ -29,4 +29,32 @@ #define _MSC_STDINT_H_ 1 #endif +#include + +template::value && std::is_unsigned::value, int>::type = 0> +T zend_mm_fast_alloc(S len) { + return static_cast(emalloc(len)); +} + +// we try to provide enough flexibility for nm and size types as long they re unsigned together +template::value && std::is_unsigned::value && std::is_integral::value && std::is_unsigned::value, int>::type = 0> +T zend_mm_safe_alloc(N num, S len, S offset = 0) { + return static_cast(safe_emalloc(num, len, offset)); +} + +template::value, int>::type = 0> +void zend_mm_destructor(T *inst) { + if (inst) { + inst->~T(); + efree(inst); + } +} + +template::value, int>::type = 0> +void zend_mm_destructor(T *ptr) { + if (ptr) { + efree(ptr); + } +} #endif