Created
October 23, 2014 09:46
-
-
Save laruence/a368a47cbe7b21b96534 to your computer and use it in GitHub Desktop.
concat_function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c | |
index 03e913c..df918e4 100644 | |
--- a/Zend/zend_operators.c | |
+++ b/Zend/zend_operators.c | |
@@ -1525,36 +1525,40 @@ ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2 | |
ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ | |
{ | |
- zval op1_copy, op2_copy; | |
+ zend_string *op1_str, *op2_str; | |
int use_copy1 = 0, use_copy2 = 0; | |
- if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) { | |
- ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function); | |
- use_copy1 = zend_make_printable_zval(op1, &op1_copy TSRMLS_CC); | |
- if (use_copy1) { | |
+ do { | |
+ if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) { | |
+ ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function); | |
+ use_copy1 = 1; | |
+ op1_str = zval_get_string(op1); | |
/* We have created a converted copy of op1. Therefore, op1 won't become the result so | |
* we have to free it. | |
*/ | |
if (result == op1) { | |
zval_dtor(op1); | |
if (UNEXPECTED(op1 == op2)) { | |
- op2 = &op1_copy; | |
+ op2_str = op1_str; | |
+ break; | |
} | |
} | |
- op1 = &op1_copy; | |
+ } else { | |
+ op1_str = Z_STR_P(op1); | |
} | |
- } | |
- if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) { | |
- ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT); | |
- use_copy2 = zend_make_printable_zval(op2, &op2_copy TSRMLS_CC); | |
- if (use_copy2) { | |
- op2 = &op2_copy; | |
+ | |
+ if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) { | |
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT); | |
+ use_copy2 = 1; | |
+ op2_str = zval_get_string(op2); | |
+ } else { | |
+ op2_str = Z_STR_P(op2); | |
} | |
- } | |
+ } while (0); | |
{ | |
- size_t op1_len = Z_STRLEN_P(op1); | |
- size_t op2_len = Z_STRLEN_P(op2); | |
+ size_t op1_len = op1_str->len; | |
+ size_t op2_len = op2_str->len; | |
size_t result_len = op1_len + op2_len; | |
zend_string *result_str; | |
@@ -1565,9 +1569,12 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{ | |
if (result == op1 && Z_REFCOUNTED_P(result)) { | |
/* special case, perform operations on result */ | |
result_str = zend_string_realloc(Z_STR_P(result), result_len, 0); | |
+ if (UNEXPECTED(op1 == op2)) { | |
+ op2_str = result_str; | |
+ } | |
} else { | |
result_str = zend_string_alloc(result_len, 0); | |
- memcpy(result_str->val, Z_STRVAL_P(op1), op1_len); | |
+ memcpy(result_str->val, op1_str->val, op1_len); | |
} | |
/* This has to happen first to account for the cases where result == op1 == op2 and | |
@@ -1575,15 +1582,15 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{ | |
* point to the new string. The first op2_len bytes of result will still be the same. */ | |
ZVAL_NEW_STR(result, result_str); | |
- memcpy(result_str->val + op1_len, Z_STRVAL_P(op2), op2_len); | |
+ memcpy(result_str->val + op1_len, op2_str->val, op2_len); | |
result_str->val[result_len] = '\0'; | |
} | |
if (UNEXPECTED(use_copy1)) { | |
- zval_dtor(op1); | |
+ zend_string_release(op1_str); | |
} | |
if (UNEXPECTED(use_copy2)) { | |
- zval_dtor(op2); | |
+ zend_string_release(op2_str); | |
} | |
return SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment