diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index f53032fabc35..bc78faa7b399 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -96,9 +96,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_); } /* }}} */ diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index de51ee745711..0ec86f208619 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -87,6 +87,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); void _bc_free_num_ex(bc_num *num, bool persistent); diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index cef55324689f..6bb538ef1cb1 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -82,6 +82,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; +} + /* Make a copy of a number! Just increments the reference count! */ bc_num bc_copy_num(bc_num num) diff --git a/ext/bcmath/tests/gh17398.phpt b/ext/bcmath/tests/gh17398.phpt new file mode 100644 index 000000000000..6a0cda09ec76 --- /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