@@ -2877,6 +2877,18 @@ ZEND_API char* ZEND_FASTCALL zend_str_toupper_dup_ex(const char *source, size_t
2877
2877
}
2878
2878
/* }}} */
2879
2879
2880
+ static zend_string * ZEND_FASTCALL zend_string_alloc_or_partial_dup (zend_string * str , bool persistent , const unsigned char * p )
2881
+ {
2882
+ if (persistent || !zend_may_modify_string_in_place (str )) {
2883
+ zend_string * res = zend_string_alloc (ZSTR_LEN (str ), persistent );
2884
+ memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2885
+ return res ;
2886
+ } else {
2887
+ zend_string_forget_hash_val (str );
2888
+ return str ;
2889
+ }
2890
+ }
2891
+
2880
2892
ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex (zend_string * str , bool persistent ) /* {{{ */
2881
2893
{
2882
2894
size_t length = ZSTR_LEN (str );
@@ -2888,8 +2900,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
2888
2900
while (p + BLOCKCONV_STRIDE <= end ) {
2889
2901
BLOCKCONV_LOAD (p );
2890
2902
if (BLOCKCONV_FOUND ()) {
2891
- zend_string * res = zend_string_alloc (length , persistent );
2892
- memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2903
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2893
2904
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2894
2905
2895
2906
/* Lowercase the chunk we already compared. */
@@ -2909,8 +2920,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
2909
2920
2910
2921
while (p < end ) {
2911
2922
if (* p != zend_tolower_ascii (* p )) {
2912
- zend_string * res = zend_string_alloc (length , persistent );
2913
- memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2923
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2914
2924
2915
2925
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2916
2926
while (p < end ) {
@@ -2937,8 +2947,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
2937
2947
while (p + BLOCKCONV_STRIDE <= end ) {
2938
2948
BLOCKCONV_LOAD (p );
2939
2949
if (BLOCKCONV_FOUND ()) {
2940
- zend_string * res = zend_string_alloc (length , persistent );
2941
- memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2950
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2942
2951
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2943
2952
2944
2953
/* Uppercase the chunk we already compared. */
@@ -2958,8 +2967,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
2958
2967
2959
2968
while (p < end ) {
2960
2969
if (* p != zend_toupper_ascii (* p )) {
2961
- zend_string * res = zend_string_alloc (length , persistent );
2962
- memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2970
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2963
2971
2964
2972
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2965
2973
while (p < end ) {
0 commit comments