@@ -2117,7 +2117,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
2117
2117
#if HAVE_LIBDL
2118
2118
#if !(defined(NETWARE ) && defined(APACHE_1_BUILD ))
2119
2119
if (module -> handle ) {
2120
- DL_UNLOAD (module -> handle );
2120
+ // DL_UNLOAD(module->handle);
2121
2121
}
2122
2122
#endif
2123
2123
#endif
@@ -2335,12 +2335,13 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_
2335
2335
}
2336
2336
/* }}} */
2337
2337
2338
- static int zend_is_callable_check_class (const char * name , int name_len , zend_fcall_info_cache * fcc , char * * error TSRMLS_DC ) /* {{{ */
2338
+ static int zend_is_callable_check_class (const char * name , int name_len , zend_fcall_info_cache * fcc , int * strict_class , char * * error TSRMLS_DC ) /* {{{ */
2339
2339
{
2340
2340
int ret = 0 ;
2341
2341
zend_class_entry * * pce ;
2342
2342
char * lcname = zend_str_tolower_dup (name , name_len );
2343
2343
2344
+ * strict_class = 0 ;
2344
2345
if (name_len == sizeof ("self" ) - 1 &&
2345
2346
!memcmp (lcname , "self" , sizeof ("self" ) - 1 )) {
2346
2347
if (!EG (scope )) {
@@ -2365,6 +2366,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
2365
2366
if (!fcc -> object_ptr ) {
2366
2367
fcc -> object_ptr = EG (This );
2367
2368
}
2369
+ * strict_class = 1 ;
2368
2370
ret = 1 ;
2369
2371
}
2370
2372
} else if (name_len == sizeof ("static" ) - 1 &&
@@ -2377,6 +2379,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
2377
2379
if (!fcc -> object_ptr ) {
2378
2380
fcc -> object_ptr = EG (This );
2379
2381
}
2382
+ * strict_class = 1 ;
2380
2383
ret = 1 ;
2381
2384
}
2382
2385
} else if (zend_lookup_class_ex (name , name_len , 1 , & pce TSRMLS_CC ) == SUCCESS ) {
@@ -2391,6 +2394,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
2391
2394
} else {
2392
2395
fcc -> called_scope = fcc -> object_ptr ? Z_OBJCE_P (fcc -> object_ptr ) : fcc -> calling_scope ;
2393
2396
}
2397
+ * strict_class = 1 ;
2394
2398
ret = 1 ;
2395
2399
} else {
2396
2400
if (error ) zend_spprintf (error , 0 , "class '%.*s' not found" , name_len , name );
@@ -2401,7 +2405,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
2401
2405
/* }}} */
2402
2406
2403
2407
2404
- static int zend_is_callable_check_func (int check_flags , zval * callable , zend_fcall_info_cache * fcc , char * * error TSRMLS_DC ) /* {{{ */
2408
+ static int zend_is_callable_check_func (int check_flags , zval * callable , zend_fcall_info_cache * fcc , int strict_class , char * * error TSRMLS_DC ) /* {{{ */
2405
2409
{
2406
2410
zend_class_entry * ce_org = fcc -> calling_scope ;
2407
2411
int retval = 0 ;
@@ -2459,7 +2463,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
2459
2463
EG (scope ) = ce_org ;
2460
2464
}
2461
2465
2462
- if (!zend_is_callable_check_class (Z_STRVAL_P (callable ), clen , fcc , error TSRMLS_CC )) {
2466
+ if (!zend_is_callable_check_class (Z_STRVAL_P (callable ), clen , fcc , & strict_class , error TSRMLS_CC )) {
2463
2467
EG (scope ) = last_scope ;
2464
2468
return 0 ;
2465
2469
}
@@ -2486,7 +2490,15 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
2486
2490
}
2487
2491
2488
2492
lmname = zend_str_tolower_dup (mname , mlen );
2489
- if (zend_hash_find (ftable , lmname , mlen + 1 , (void * * )& fcc -> function_handler ) == SUCCESS ) {
2493
+ if (strict_class &&
2494
+ fcc -> calling_scope &&
2495
+ mlen == sizeof (ZEND_CONSTRUCTOR_FUNC_NAME )- 1 &&
2496
+ !memcmp (lmname , ZEND_CONSTRUCTOR_FUNC_NAME , sizeof (ZEND_CONSTRUCTOR_FUNC_NAME ))) {
2497
+ fcc -> function_handler = fcc -> calling_scope -> constructor ;
2498
+ if (fcc -> function_handler ) {
2499
+ retval = 1 ;
2500
+ }
2501
+ } else if (zend_hash_find (ftable , lmname , mlen + 1 , (void * * )& fcc -> function_handler ) == SUCCESS ) {
2490
2502
retval = 1 ;
2491
2503
if ((fcc -> function_handler -> op_array .fn_flags & ZEND_ACC_CHANGED ) &&
2492
2504
EG (scope ) &&
@@ -2520,11 +2532,36 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
2520
2532
} else {
2521
2533
get_function_via_handler :
2522
2534
if (fcc -> object_ptr && fcc -> calling_scope == ce_org ) {
2523
- if (Z_OBJ_HT_P (fcc -> object_ptr )-> get_method ) {
2535
+ if (strict_class && ce_org -> __call ) {
2536
+ fcc -> function_handler = emalloc (sizeof (zend_internal_function ));
2537
+ fcc -> function_handler -> internal_function .type = ZEND_INTERNAL_FUNCTION ;
2538
+ fcc -> function_handler -> internal_function .module = ce_org -> module ;
2539
+ fcc -> function_handler -> internal_function .handler = zend_std_call_user_call ;
2540
+ fcc -> function_handler -> internal_function .arg_info = NULL ;
2541
+ fcc -> function_handler -> internal_function .num_args = 0 ;
2542
+ fcc -> function_handler -> internal_function .scope = ce_org ;
2543
+ fcc -> function_handler -> internal_function .fn_flags = ZEND_ACC_CALL_VIA_HANDLER ;
2544
+ fcc -> function_handler -> internal_function .function_name = estrndup (mname , mlen );
2545
+ fcc -> function_handler -> internal_function .pass_rest_by_reference = 0 ;
2546
+ fcc -> function_handler -> internal_function .return_reference = ZEND_RETURN_VALUE ;
2547
+ call_via_handler = 1 ;
2548
+ retval = 1 ;
2549
+ } else if (Z_OBJ_HT_P (fcc -> object_ptr )-> get_method ) {
2524
2550
fcc -> function_handler = Z_OBJ_HT_P (fcc -> object_ptr )-> get_method (& fcc -> object_ptr , mname , mlen TSRMLS_CC );
2525
2551
if (fcc -> function_handler ) {
2526
- retval = 1 ;
2527
- call_via_handler = (fcc -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) != 0 ;
2552
+ if (strict_class &&
2553
+ (!fcc -> function_handler -> common .scope ||
2554
+ !instanceof_function (ce_org , fcc -> function_handler -> common .scope TSRMLS_CC ))) {
2555
+ if ((fcc -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) != 0 ) {
2556
+ if (fcc -> function_handler -> type != ZEND_OVERLOADED_FUNCTION ) {
2557
+ efree (fcc -> function_handler -> common .function_name );
2558
+ }
2559
+ efree (fcc -> function_handler );
2560
+ }
2561
+ } else {
2562
+ retval = 1 ;
2563
+ call_via_handler = (fcc -> function_handler -> common .fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) != 0 ;
2564
+ }
2528
2565
}
2529
2566
}
2530
2567
} else if (fcc -> calling_scope ) {
@@ -2680,7 +2717,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
2680
2717
return 1 ;
2681
2718
}
2682
2719
2683
- ret = zend_is_callable_check_func (check_flags , callable , fcc , error TSRMLS_CC );
2720
+ ret = zend_is_callable_check_func (check_flags , callable , fcc , 0 , error TSRMLS_CC );
2684
2721
if (fcc == & fcc_local &&
2685
2722
fcc -> function_handler &&
2686
2723
((fcc -> function_handler -> type == ZEND_INTERNAL_FUNCTION &&
@@ -2698,6 +2735,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
2698
2735
{
2699
2736
zval * * method = NULL ;
2700
2737
zval * * obj = NULL ;
2738
+ int strict_class = 0 ;
2701
2739
2702
2740
if (zend_hash_num_elements (Z_ARRVAL_P (callable )) == 2 ) {
2703
2741
zend_hash_index_find (Z_ARRVAL_P (callable ), 0 , (void * * ) & obj );
@@ -2725,7 +2763,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
2725
2763
return 1 ;
2726
2764
}
2727
2765
2728
- if (!zend_is_callable_check_class (Z_STRVAL_PP (obj ), Z_STRLEN_PP (obj ), fcc , error TSRMLS_CC )) {
2766
+ if (!zend_is_callable_check_class (Z_STRVAL_PP (obj ), Z_STRLEN_PP (obj ), fcc , & strict_class , error TSRMLS_CC )) {
2729
2767
return 0 ;
2730
2768
}
2731
2769
@@ -2757,7 +2795,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
2757
2795
}
2758
2796
}
2759
2797
2760
- ret = zend_is_callable_check_func (check_flags , * method , fcc , error TSRMLS_CC );
2798
+ ret = zend_is_callable_check_func (check_flags , * method , fcc , strict_class , error TSRMLS_CC );
2761
2799
if (fcc == & fcc_local &&
2762
2800
fcc -> function_handler &&
2763
2801
((fcc -> function_handler -> type == ZEND_INTERNAL_FUNCTION &&
0 commit comments