mirror of
https://github.com/php/php-src.git
synced 2024-12-15 04:45:03 +08:00
Fix overflow check for string concatenation
Also do the overflow check for both branches, not just the realloc one. And clean up the code a bit - move common parts outside of the realloc/alloc branches.
This commit is contained in:
parent
e06f5f0df8
commit
08ca9e6d11
@ -1529,29 +1529,28 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
|
|||||||
op2 = &op2_copy;
|
op2 = &op2_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result==op1 && !IS_INTERNED(Z_STR_P(op1))) { /* special case, perform operations on result */
|
{
|
||||||
size_t op1_len = Z_STRLEN_P(op1);
|
size_t op1_len = Z_STRLEN_P(op1);
|
||||||
size_t op2_len = Z_STRLEN_P(op2);
|
size_t result_len = op1_len + Z_STRLEN_P(op2);
|
||||||
size_t res_len = op1_len + op2_len;
|
zend_string *result_str;
|
||||||
|
|
||||||
if (Z_STRLEN_P(result) < 0 || (size_t) (op1_len + op2_len) < 0) {
|
if (op1_len > SIZE_MAX - Z_STRLEN_P(op2)) {
|
||||||
ZVAL_EMPTY_STRING(result);
|
zend_error_noreturn(E_ERROR, "String size overflow");
|
||||||
zend_error(E_ERROR, "String size overflow");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Z_STR_P(result) = zend_string_realloc(Z_STR_P(result), res_len, 0 );
|
if (result == op1 && !IS_INTERNED(Z_STR_P(op1))) {
|
||||||
Z_TYPE_INFO_P(result) = IS_STRING_EX;
|
/* special case, perform operations on result */
|
||||||
memcpy(Z_STRVAL_P(result) + op1_len, Z_STRVAL_P(op2), op2_len);
|
result_str = zend_string_realloc(Z_STR_P(result), result_len, 0);
|
||||||
Z_STRVAL_P(result)[res_len]=0;
|
} else {
|
||||||
} else {
|
result_str = zend_string_alloc(result_len, 0);
|
||||||
size_t length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
|
memcpy(result_str->val, Z_STRVAL_P(op1), op1_len);
|
||||||
zend_string *buf = zend_string_alloc(length, 0);
|
}
|
||||||
|
|
||||||
memcpy(buf->val, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
|
memcpy(result_str->val + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
|
||||||
memcpy(buf->val + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
|
result_str->val[result_len] = '\0';
|
||||||
buf->val[length] = 0;
|
ZVAL_NEW_STR(result, result_str);
|
||||||
ZVAL_NEW_STR(result, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNEXPECTED(use_copy1)) {
|
if (UNEXPECTED(use_copy1)) {
|
||||||
zval_dtor(op1);
|
zval_dtor(op1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user