@@ -522,6 +522,9 @@ void * zend_test_custom_malloc(size_t len)
522
522
if (has_opline (EG (current_execute_data ))) {
523
523
assert (EG (current_execute_data )-> opline -> lineno != (uint32_t )-1 );
524
524
}
525
+ if (ZT_G (zendmm_orig_malloc )) {
526
+ return ZT_G (zendmm_orig_malloc )(len );
527
+ }
525
528
return _zend_mm_alloc (ZT_G (zend_orig_heap ), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC );
526
529
}
527
530
@@ -530,6 +533,10 @@ void zend_test_custom_free(void *ptr)
530
533
if (has_opline (EG (current_execute_data ))) {
531
534
assert (EG (current_execute_data )-> opline -> lineno != (uint32_t )-1 );
532
535
}
536
+ if (ZT_G (zendmm_orig_free )) {
537
+ ZT_G (zendmm_orig_free )(ptr );
538
+ return ;
539
+ }
533
540
_zend_mm_free (ZT_G (zend_orig_heap ), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC );
534
541
}
535
542
@@ -538,9 +545,47 @@ void * zend_test_custom_realloc(void * ptr, size_t len)
538
545
if (has_opline (EG (current_execute_data ))) {
539
546
assert (EG (current_execute_data )-> opline -> lineno != (uint32_t )-1 );
540
547
}
548
+ if (ZT_G (zendmm_orig_realloc )) {
549
+ return ZT_G (zendmm_orig_realloc )(ptr , len );
550
+ }
541
551
return _zend_mm_realloc (ZT_G (zend_orig_heap ), ptr , len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC );
542
552
}
543
553
554
+ void zend_test_install_custom_mm_handler (void )
555
+ {
556
+ // fetch maybe installed previous handlers
557
+ if (!is_zend_mm ()) {
558
+ zend_mm_get_custom_handlers (
559
+ zend_mm_get_heap (),
560
+ & ZT_G (zendmm_orig_malloc ),
561
+ & ZT_G (zendmm_orig_free ),
562
+ & ZT_G (zendmm_orig_realloc )
563
+ );
564
+ }
565
+ // `zend_mm_heap` is a private struct, so we have not way to find the
566
+ // actual size, but 4096 bytes should be enough
567
+ ZT_G (zend_test_heap ) = malloc (4096 );
568
+ memset (ZT_G (zend_test_heap ), 0 , 4096 );
569
+ zend_mm_set_custom_handlers (
570
+ ZT_G (zend_test_heap ),
571
+ zend_test_custom_malloc ,
572
+ zend_test_custom_free ,
573
+ zend_test_custom_realloc
574
+ );
575
+ ZT_G (zend_orig_heap ) = zend_mm_get_heap ();
576
+ zend_mm_set_heap (ZT_G (zend_test_heap ));
577
+ }
578
+
579
+ void zend_test_uninstall_custom_mm_handler (void )
580
+ {
581
+ free (ZT_G (zend_test_heap ));
582
+ ZT_G (zend_test_heap ) = NULL ;
583
+ ZT_G (zendmm_orig_malloc ) = NULL ;
584
+ ZT_G (zendmm_orig_free ) = NULL ;
585
+ ZT_G (zendmm_orig_realloc ) = NULL ;
586
+ zend_mm_set_heap (ZT_G (zend_orig_heap ));
587
+ }
588
+
544
589
static PHP_INI_MH (OnUpdateZendTestObserveOplineInZendMM )
545
590
{
546
591
if (new_value == NULL ) {
@@ -550,22 +595,9 @@ static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
550
595
int int_value = zend_ini_parse_bool (new_value );
551
596
552
597
if (int_value == 1 ) {
553
- // `zend_mm_heap` is a private struct, so we have not way to find the
554
- // actual size, but 4096 bytes should be enough
555
- ZT_G (zend_test_heap ) = malloc (4096 );
556
- memset (ZT_G (zend_test_heap ), 0 , 4096 );
557
- zend_mm_set_custom_handlers (
558
- ZT_G (zend_test_heap ),
559
- zend_test_custom_malloc ,
560
- zend_test_custom_free ,
561
- zend_test_custom_realloc
562
- );
563
- ZT_G (zend_orig_heap ) = zend_mm_get_heap ();
564
- zend_mm_set_heap (ZT_G (zend_test_heap ));
598
+ zend_test_install_custom_mm_handler ();
565
599
} else if (ZT_G (zend_test_heap )) {
566
- free (ZT_G (zend_test_heap ));
567
- ZT_G (zend_test_heap ) = NULL ;
568
- zend_mm_set_heap (ZT_G (zend_orig_heap ));
600
+ zend_test_uninstall_custom_mm_handler ();
569
601
}
570
602
return OnUpdateBool (entry , new_value , mh_arg1 , mh_arg2 , mh_arg3 , stage );
571
603
}
@@ -971,9 +1003,7 @@ PHP_RSHUTDOWN_FUNCTION(zend_test)
971
1003
zend_hash_destroy (& ZT_G (global_weakmap ));
972
1004
973
1005
if (ZT_G (zend_test_heap )) {
974
- free (ZT_G (zend_test_heap ));
975
- ZT_G (zend_test_heap ) = NULL ;
976
- zend_mm_set_heap (ZT_G (zend_orig_heap ));
1006
+ zend_test_uninstall_custom_mm_handler ();
977
1007
}
978
1008
979
1009
return SUCCESS ;
0 commit comments