@@ -2877,7 +2877,21 @@ ZEND_API char* ZEND_FASTCALL zend_str_toupper_dup_ex(const char *source, size_t
28772877}
28782878/* }}} */
28792879
2880- ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex (zend_string * str , bool persistent ) /* {{{ */
2880+ static zend_string * ZEND_FASTCALL zend_string_alloc_or_partial_dup (zend_string * str , bool persistent , bool inplace , const unsigned char * p )
2881+ {
2882+ if (inplace ) {
2883+ ZEND_ASSERT (!persistent );
2884+ zend_string_forget_hash_val (str );
2885+ GC_ADDREF (str );
2886+ return str ;
2887+ } else {
2888+ zend_string * res = zend_string_alloc (ZSTR_LEN (str ), persistent );
2889+ memcpy (ZSTR_VAL (res ), ZSTR_VAL (str ), p - (unsigned char * ) ZSTR_VAL (str ));
2890+ return res ;
2891+ }
2892+ }
2893+
2894+ ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex_maybe_inplace (zend_string * str , bool persistent , bool inplace ) /* {{{ */
28812895{
28822896 size_t length = ZSTR_LEN (str );
28832897 unsigned char * p = (unsigned char * ) ZSTR_VAL (str );
@@ -2888,8 +2902,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
28882902 while (p + BLOCKCONV_STRIDE <= end ) {
28892903 BLOCKCONV_LOAD (p );
28902904 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 ));
2905+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , inplace , p );
28932906 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
28942907
28952908 /* Lowercase the chunk we already compared. */
@@ -2909,8 +2922,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
29092922
29102923 while (p < end ) {
29112924 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 ));
2925+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , inplace , p );
29142926
29152927 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29162928 while (p < end ) {
@@ -2926,7 +2938,12 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
29262938}
29272939/* }}} */
29282940
2929- ZEND_API zend_string * ZEND_FASTCALL zend_string_toupper_ex (zend_string * str , bool persistent ) /* {{{ */
2941+ ZEND_API zend_string * ZEND_FASTCALL zend_string_tolower_ex (zend_string * str , bool persistent )
2942+ {
2943+ return zend_string_tolower_ex_maybe_inplace (str , persistent , false);
2944+ }
2945+
2946+ ZEND_API zend_string * ZEND_FASTCALL zend_string_toupper_ex_maybe_inplace (zend_string * str , bool persistent , bool inplace ) /* {{{ */
29302947{
29312948 size_t length = ZSTR_LEN (str );
29322949 unsigned char * p = (unsigned char * ) ZSTR_VAL (str );
@@ -2937,8 +2954,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29372954 while (p + BLOCKCONV_STRIDE <= end ) {
29382955 BLOCKCONV_LOAD (p );
29392956 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 ));
2957+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , inplace , p );
29422958 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29432959
29442960 /* Uppercase the chunk we already compared. */
@@ -2958,8 +2974,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29582974
29592975 while (p < end ) {
29602976 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 ));
2977+ zend_string * res = zend_string_alloc_or_partial_dup (str , persistent , inplace , p );
29632978
29642979 unsigned char * q = (unsigned char * ) ZSTR_VAL (res ) + (p - (unsigned char * ) ZSTR_VAL (str ));
29652980 while (p < end ) {
@@ -2975,6 +2990,11 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29752990}
29762991/* }}} */
29772992
2993+ ZEND_API zend_string * ZEND_FASTCALL zend_string_toupper_ex (zend_string * str , bool persistent )
2994+ {
2995+ return zend_string_toupper_ex_maybe_inplace (str , persistent , false);
2996+ }
2997+
29782998ZEND_API int ZEND_FASTCALL zend_binary_strcmp (const char * s1 , size_t len1 , const char * s2 , size_t len2 ) /* {{{ */
29792999{
29803000 int retval ;
0 commit comments