@@ -2877,6 +2877,17 @@ 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
+ return str ;
2888
+ }
2889
+ }
2890
+
2880
2891
ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex (zend_string * str , bool persistent ) /* {{{ */
2881
2892
{
2882
2893
size_t length = ZSTR_LEN (str );
@@ -2888,8 +2899,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
2888
2899
while (p + BLOCKCONV_STRIDE <= end ) {
2889
2900
BLOCKCONV_LOAD (p );
2890
2901
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 ));
2902
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2893
2903
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2894
2904
2895
2905
/* Lowercase the chunk we already compared. */
@@ -2909,8 +2919,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
2909
2919
2910
2920
while (p < end ) {
2911
2921
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 ));
2922
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2914
2923
2915
2924
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2916
2925
while (p < end ) {
@@ -2937,8 +2946,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
2937
2946
while (p + BLOCKCONV_STRIDE <= end ) {
2938
2947
BLOCKCONV_LOAD (p );
2939
2948
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 ));
2949
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2942
2950
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2943
2951
2944
2952
/* Uppercase the chunk we already compared. */
@@ -2958,8 +2966,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
2958
2966
2959
2967
while (p < end ) {
2960
2968
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 ));
2969
+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , p );
2963
2970
2964
2971
unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
2965
2972
while (p < end ) {
0 commit comments