@@ -2877,6 +2877,17 @@ ZEND_API char* ZEND_FASTCALL zend_str_toupper_dup_ex(const char *source, size_t
28772877}
28782878/* }}} */
28792879
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+
28802891ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex (zend_string * str , bool persistent ) /* {{{ */
28812892{
28822893 size_t length = ZSTR_LEN (str );
@@ -2888,8 +2899,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
28882899 while (p + BLOCKCONV_STRIDE <= end ) {
28892900 BLOCKCONV_LOAD (p );
28902901 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 );
28932903 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
28942904
28952905 /* Lowercase the chunk we already compared. */
@@ -2909,8 +2919,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
29092919
29102920 while (p < end ) {
29112921 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 );
29142923
29152924 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29162925 while (p < end ) {
@@ -2937,8 +2946,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29372946 while (p + BLOCKCONV_STRIDE <= end ) {
29382947 BLOCKCONV_LOAD (p );
29392948 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 );
29422950 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29432951
29442952 /* Uppercase the chunk we already compared. */
@@ -2958,8 +2966,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29582966
29592967 while (p < end ) {
29602968 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 );
29632970
29642971 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29652972 while (p < end ) {
0 commit comments