@@ -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