@@ -2951,12 +2951,21 @@ typedef enum {
2951
2951
MB_BOTH_TRIM = 3
2952
2952
} mb_trim_mode ;
2953
2953
2954
- static zend_always_inline bool is_trim_wchar (uint32_t w , const HashTable * ht )
2954
+ static bool is_trim_wchar (uint32_t w , const HashTable * ht , const uint32_t * default_chars , size_t default_chars_length )
2955
2955
{
2956
- return zend_hash_index_exists (ht , w );
2956
+ if (ht ) {
2957
+ return zend_hash_index_exists (ht , w );
2958
+ } else {
2959
+ for (size_t i = 0 ; i < default_chars_length ; i ++ ) {
2960
+ if (w == default_chars [i ]) {
2961
+ return true;
2962
+ }
2963
+ }
2964
+ return false;
2965
+ }
2957
2966
}
2958
2967
2959
- static zend_string * trim_each_wchar (zend_string * str , const HashTable * what_ht , mb_trim_mode mode , const mbfl_encoding * enc )
2968
+ static zend_string * trim_each_wchar (zend_string * str , const HashTable * what_ht , const uint32_t * default_chars , size_t default_chars_length , mb_trim_mode mode , const mbfl_encoding * enc )
2960
2969
{
2961
2970
unsigned char * in = (unsigned char * )ZSTR_VAL (str );
2962
2971
uint32_t wchar_buf [128 ];
@@ -2974,7 +2983,7 @@ static zend_string* trim_each_wchar(zend_string *str, const HashTable *what_ht,
2974
2983
2975
2984
for (size_t i = 0 ; i < out_len ; i ++ ) {
2976
2985
uint32_t w = wchar_buf [i ];
2977
- if (is_trim_wchar (w , what_ht )) {
2986
+ if (is_trim_wchar (w , what_ht , default_chars , default_chars_length )) {
2978
2987
if (mode & MB_LTRIM ) {
2979
2988
left += 1 ;
2980
2989
}
@@ -2990,6 +2999,9 @@ static zend_string* trim_each_wchar(zend_string *str, const HashTable *what_ht,
2990
2999
}
2991
3000
}
2992
3001
3002
+ if (left == 0 && right == 0 ) {
3003
+ return zend_string_copy (str );
3004
+ }
2993
3005
return mb_get_substr (str , left , total_len - (right + left ), enc );
2994
3006
}
2995
3007
@@ -3012,7 +3024,7 @@ static zend_string* mb_trim_default_chars(zend_string *str, mb_trim_mode mode, c
3012
3024
for (size_t i = 0 ; i < trim_default_chars_length ; i ++ ) {
3013
3025
zend_hash_index_add_new (& what_ht , trim_default_chars [i ], & val );
3014
3026
}
3015
- zend_string * retval = trim_each_wchar (str , & what_ht , mode , enc );
3027
+ zend_string * retval = trim_each_wchar (str , & what_ht , NULL , 0 , mode , enc );
3016
3028
zend_hash_destroy (& what_ht );
3017
3029
3018
3030
return retval ;
@@ -3027,18 +3039,32 @@ static zend_string* mb_trim_what_chars(zend_string *str, zend_string *what, mb_t
3027
3039
size_t what_len = ZSTR_LEN (what );
3028
3040
HashTable what_ht ;
3029
3041
zval val ;
3030
- ZVAL_TRUE (& val );
3031
- zend_hash_init (& what_ht , what_len , NULL , NULL , false);
3042
+ bool hash_initialized = false;
3032
3043
3033
3044
while (what_len ) {
3034
3045
what_out_len = enc -> to_wchar (& what_in , & what_len , what_wchar_buf , 128 , & state );
3035
3046
ZEND_ASSERT (what_out_len <= 128 );
3036
- for (size_t i = 0 ; i < what_out_len ; i ++ ) {
3037
- zend_hash_index_add (& what_ht , what_wchar_buf [i ], & val );
3047
+
3048
+ if (what_out_len <= 4 && !hash_initialized ) {
3049
+ return trim_each_wchar (str , NULL , what_wchar_buf , what_out_len , mode , enc );
3050
+ } else {
3051
+ if (!hash_initialized ) {
3052
+ hash_initialized = true;
3053
+ ZVAL_TRUE (& val );
3054
+ zend_hash_init (& what_ht , what_len , NULL , NULL , false);
3055
+ }
3056
+ for (size_t i = 0 ; i < what_out_len ; i ++ ) {
3057
+ zend_hash_index_add (& what_ht , what_wchar_buf [i ], & val );
3058
+ }
3038
3059
}
3039
3060
}
3040
3061
3041
- zend_string * retval = trim_each_wchar (str , & what_ht , mode , enc );
3062
+ if (UNEXPECTED (!hash_initialized )) {
3063
+ /* This is only possible if what is empty */
3064
+ return zend_string_copy (str );
3065
+ }
3066
+
3067
+ zend_string * retval = trim_each_wchar (str , & what_ht , NULL , 0 , mode , enc );
3042
3068
zend_hash_destroy (& what_ht );
3043
3069
3044
3070
return retval ;
0 commit comments