2929#include "php_bcmath.h"
3030#include "libbcmath/src/bcmath.h"
3131
32+ /* Always pair SETUP with TEARDOWN, and do so in the outer scope!
33+ * Should not be used when data can escape the function. */
34+ #define BC_ARENA_SETUP \
35+ char bc_arena[BC_ARENA_SIZE]; \
36+ BCG(arena) = bc_arena;
37+
38+ #define BC_ARENA_TEARDOWN \
39+ BCG(arena) = NULL; \
40+ BCG(arena_offset) = 0;
41+
3242ZEND_DECLARE_MODULE_GLOBALS (bcmath )
3343static PHP_GINIT_FUNCTION (bcmath );
3444static PHP_GSHUTDOWN_FUNCTION (bcmath );
@@ -89,6 +99,8 @@ static PHP_GINIT_FUNCTION(bcmath)
8999 ZEND_TSRMLS_CACHE_UPDATE ();
90100#endif
91101 bcmath_globals -> bc_precision = 0 ;
102+ bcmath_globals -> arena = NULL ;
103+ bcmath_globals -> arena_offset = 0 ;
92104 bc_init_numbers ();
93105}
94106/* }}} */
@@ -99,6 +111,8 @@ static PHP_GSHUTDOWN_FUNCTION(bcmath)
99111 _bc_free_num_ex (& bcmath_globals -> _zero_ , 1 );
100112 _bc_free_num_ex (& bcmath_globals -> _one_ , 1 );
101113 _bc_free_num_ex (& bcmath_globals -> _two_ , 1 );
114+ bcmath_globals -> arena = NULL ;
115+ bcmath_globals -> arena_offset = 0 ;
102116}
103117/* }}} */
104118
@@ -167,6 +181,8 @@ PHP_FUNCTION(bcadd)
167181 scale = (int ) scale_param ;
168182 }
169183
184+ BC_ARENA_SETUP ;
185+
170186 if (php_str2num (& first , left ) == FAILURE ) {
171187 zend_argument_value_error (1 , "is not well-formed" );
172188 goto cleanup ;
@@ -185,6 +201,7 @@ PHP_FUNCTION(bcadd)
185201 bc_free_num (& first );
186202 bc_free_num (& second );
187203 bc_free_num (& result );
204+ BC_ARENA_TEARDOWN ;
188205 };
189206}
190207/* }}} */
@@ -214,6 +231,8 @@ PHP_FUNCTION(bcsub)
214231 scale = (int ) scale_param ;
215232 }
216233
234+ BC_ARENA_SETUP ;
235+
217236 if (php_str2num (& first , left ) == FAILURE ) {
218237 zend_argument_value_error (1 , "is not well-formed" );
219238 goto cleanup ;
@@ -232,6 +251,7 @@ PHP_FUNCTION(bcsub)
232251 bc_free_num (& first );
233252 bc_free_num (& second );
234253 bc_free_num (& result );
254+ BC_ARENA_TEARDOWN ;
235255 };
236256}
237257/* }}} */
@@ -261,6 +281,8 @@ PHP_FUNCTION(bcmul)
261281 scale = (int ) scale_param ;
262282 }
263283
284+ BC_ARENA_SETUP ;
285+
264286 if (php_str2num (& first , left ) == FAILURE ) {
265287 zend_argument_value_error (1 , "is not well-formed" );
266288 goto cleanup ;
@@ -279,6 +301,7 @@ PHP_FUNCTION(bcmul)
279301 bc_free_num (& first );
280302 bc_free_num (& second );
281303 bc_free_num (& result );
304+ BC_ARENA_TEARDOWN ;
282305 };
283306}
284307/* }}} */
@@ -308,6 +331,8 @@ PHP_FUNCTION(bcdiv)
308331 scale = (int ) scale_param ;
309332 }
310333
334+ BC_ARENA_SETUP ;
335+
311336 bc_init_num (& result );
312337
313338 if (php_str2num (& first , left ) == FAILURE ) {
@@ -331,6 +356,7 @@ PHP_FUNCTION(bcdiv)
331356 bc_free_num (& first );
332357 bc_free_num (& second );
333358 bc_free_num (& result );
359+ BC_ARENA_TEARDOWN ;
334360 };
335361}
336362/* }}} */
@@ -360,6 +386,8 @@ PHP_FUNCTION(bcmod)
360386 scale = (int ) scale_param ;
361387 }
362388
389+ BC_ARENA_SETUP ;
390+
363391 bc_init_num (& result );
364392
365393 if (php_str2num (& first , left ) == FAILURE ) {
@@ -383,6 +411,7 @@ PHP_FUNCTION(bcmod)
383411 bc_free_num (& first );
384412 bc_free_num (& second );
385413 bc_free_num (& result );
414+ BC_ARENA_TEARDOWN ;
386415 };
387416}
388417/* }}} */
@@ -413,6 +442,8 @@ PHP_FUNCTION(bcpowmod)
413442 scale = (int ) scale_param ;
414443 }
415444
445+ BC_ARENA_SETUP ;
446+
416447 bc_init_num (& result );
417448
418449 if (php_str2num (& bc_base , base_str ) == FAILURE ) {
@@ -458,6 +489,7 @@ PHP_FUNCTION(bcpowmod)
458489 bc_free_num (& bc_expo );
459490 bc_free_num (& bc_modulus );
460491 bc_free_num (& result );
492+ BC_ARENA_TEARDOWN ;
461493 };
462494}
463495/* }}} */
@@ -487,6 +519,8 @@ PHP_FUNCTION(bcpow)
487519 scale = (int ) scale_param ;
488520 }
489521
522+ BC_ARENA_SETUP ;
523+
490524 bc_init_num (& result );
491525
492526 if (php_str2num (& first , base_str ) == FAILURE ) {
@@ -518,6 +552,7 @@ PHP_FUNCTION(bcpow)
518552 bc_free_num (& first );
519553 bc_free_num (& bc_exponent );
520554 bc_free_num (& result );
555+ BC_ARENA_TEARDOWN ;
521556 };
522557}
523558/* }}} */
@@ -546,6 +581,8 @@ PHP_FUNCTION(bcsqrt)
546581 scale = (int ) scale_param ;
547582 }
548583
584+ BC_ARENA_SETUP ;
585+
549586 if (php_str2num (& result , left ) == FAILURE ) {
550587 zend_argument_value_error (1 , "is not well-formed" );
551588 goto cleanup ;
@@ -559,6 +596,7 @@ PHP_FUNCTION(bcsqrt)
559596
560597 cleanup : {
561598 bc_free_num (& result );
599+ BC_ARENA_TEARDOWN ;
562600 };
563601}
564602/* }}} */
@@ -588,6 +626,8 @@ PHP_FUNCTION(bccomp)
588626 scale = (int ) scale_param ;
589627 }
590628
629+ BC_ARENA_SETUP ;
630+
591631 if (!bc_str2num (& first , ZSTR_VAL (left ), ZSTR_VAL (left ) + ZSTR_LEN (left ), scale , false)) {
592632 zend_argument_value_error (1 , "is not well-formed" );
593633 goto cleanup ;
@@ -603,6 +643,7 @@ PHP_FUNCTION(bccomp)
603643 cleanup : {
604644 bc_free_num (& first );
605645 bc_free_num (& second );
646+ BC_ARENA_TEARDOWN ;
606647 };
607648}
608649/* }}} */
@@ -617,6 +658,8 @@ static void bcfloor_or_bcceil(INTERNAL_FUNCTION_PARAMETERS, bool is_floor)
617658 Z_PARAM_STR (numstr )
618659 ZEND_PARSE_PARAMETERS_END ();
619660
661+ BC_ARENA_SETUP ;
662+
620663 if (php_str2num (& num , numstr ) == FAILURE ) {
621664 zend_argument_value_error (1 , "is not well-formed" );
622665 goto cleanup ;
@@ -628,6 +671,7 @@ static void bcfloor_or_bcceil(INTERNAL_FUNCTION_PARAMETERS, bool is_floor)
628671 cleanup : {
629672 bc_free_num (& num );
630673 bc_free_num (& result );
674+ BC_ARENA_TEARDOWN ;
631675 };
632676}
633677/* }}} */
@@ -676,6 +720,8 @@ PHP_FUNCTION(bcround)
676720 return ;
677721 }
678722
723+ BC_ARENA_SETUP ;
724+
679725 bc_init_num (& result );
680726
681727 if (php_str2num (& num , numstr ) == FAILURE ) {
@@ -689,6 +735,7 @@ PHP_FUNCTION(bcround)
689735 cleanup : {
690736 bc_free_num (& num );
691737 bc_free_num (& result );
738+ BC_ARENA_TEARDOWN ;
692739 };
693740}
694741/* }}} */
0 commit comments