diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 832d2758fe968..233045bd7cd7e 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -109,9 +109,9 @@ static PHP_GINIT_FUNCTION(bcmath) /* {{{ PHP_GSHUTDOWN_FUNCTION */ static PHP_GSHUTDOWN_FUNCTION(bcmath) { - _bc_free_num_ex(&bcmath_globals->_zero_, 1); - _bc_free_num_ex(&bcmath_globals->_one_, 1); - _bc_free_num_ex(&bcmath_globals->_two_, 1); + bc_force_free_number(&bcmath_globals->_zero_); + bc_force_free_number(&bcmath_globals->_one_); + bc_force_free_number(&bcmath_globals->_two_); bcmath_globals->arena = NULL; bcmath_globals->arena_offset = 0; } diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index bb6eb5ca82497..f7e14019bd336 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -78,6 +78,8 @@ typedef struct bc_struct { void bc_init_numbers(void); +void bc_force_free_number(bc_num *num); + bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent); bc_num _bc_new_num_nonzeroed_ex(size_t length, size_t scale, bool persistent); diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 18efc1c39a2b2..3840811963f36 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -97,6 +97,13 @@ void bc_init_numbers(void) BCG(_two_)->n_value[0] = 2; } +void bc_force_free_number(bc_num *num) +{ + pefree((*num)->n_ptr, 1); + pefree(*num, 1); + *num = NULL; +} + /* Initialize a number NUM by making it a copy of zero. */ void bc_init_num(bc_num *num) diff --git a/ext/bcmath/tests/gh17398.phpt b/ext/bcmath/tests/gh17398.phpt new file mode 100644 index 0000000000000..6a0cda09ec76f --- /dev/null +++ b/ext/bcmath/tests/gh17398.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-17398 (bcmul memory leak) +--EXTENSIONS-- +bcmath +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d