@@ -1571,6 +1571,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
1571
1571
{
1572
1572
char * string_value ;
1573
1573
size_t string_len ;
1574
+ zend_long old_len = Z_STRLEN_P (str );
1574
1575
zend_long offset ;
1575
1576
1576
1577
offset = zend_check_string_offset (dim , BP_VAR_W EXECUTE_DATA_CC );
@@ -1611,7 +1612,6 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
1611
1612
1612
1613
if ((size_t )offset >= Z_STRLEN_P (str )) {
1613
1614
/* Extend string if needed */
1614
- zend_long old_len = Z_STRLEN_P (str );
1615
1615
ZVAL_NEW_STR (str , zend_string_extend (Z_STR_P (str ), offset + 1 , 0 ));
1616
1616
memset (Z_STRVAL_P (str ) + old_len , ' ' , offset - old_len );
1617
1617
Z_STRVAL_P (str )[offset + 1 ] = 0 ;
@@ -1633,61 +1633,42 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
1633
1633
return ;
1634
1634
}
1635
1635
1636
+ /* -1 for the byte we are replacing */
1637
+ zend_long new_len = old_len + string_len - 1 ;
1636
1638
if ((size_t )offset >= Z_STRLEN_P (str )) {
1637
- /* Extend string if needed */
1638
- zend_long old_len = Z_STRLEN_P (str );
1639
+ /* Extend string */
1639
1640
ZVAL_NEW_STR (str , zend_string_extend (Z_STR_P (str ), offset + string_len , 0 ));
1640
1641
memset (Z_STRVAL_P (str ) + old_len , ' ' , offset - old_len );
1641
- ZVAL_NEW_STR ( str , zend_string_init ( strcat ( Z_STRVAL_P (str ), string_value ), offset + string_len , 0 ) );
1642
+ memcpy ( Z_STRVAL_P (str ) + offset , string_value , string_len );
1642
1643
if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
1643
- ZVAL_INTERNED_STR (EX_VAR (opline -> result .var ), zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P (str ), 0 ));
1644
+ ZVAL_STR (EX_VAR (opline -> result .var ), zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P (str ), 0 ));
1644
1645
}
1645
1646
return ;
1646
- } else if (!Z_REFCOUNTED_P (str )) {
1647
- ZVAL_NEW_STR (str , zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P (str ), 0 ));
1647
+ }
1648
+
1649
+ zend_string * tmp = zend_string_init (Z_STRVAL_P (str ), new_len , 0 );
1650
+ if (string_len > 0 ) {
1651
+ memcpy (ZSTR_VAL (tmp ) + offset , string_value , string_len );
1652
+ }
1653
+ /* Copy after the replacement string, from the position of the initial string after the offset,
1654
+ * for the remainder of the initial string (old length - offset) */
1655
+ memcpy (ZSTR_VAL (tmp ) + offset + string_len , Z_STRVAL_P (str ) + offset + 1 , old_len - offset );
1656
+
1657
+ if (!Z_REFCOUNTED_P (str )) {
1658
+ ZVAL_NEW_STR (str , zend_string_init (Z_STRVAL_P (str ), new_len , 0 ));
1648
1659
} else if (Z_REFCOUNT_P (str ) > 1 ) {
1649
1660
Z_DELREF_P (str );
1650
- ZVAL_NEW_STR (str , zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P ( str ) , 0 ));
1661
+ ZVAL_NEW_STR (str , zend_string_init (Z_STRVAL_P (str ), new_len , 0 ));
1651
1662
} else {
1652
1663
zend_string_forget_hash_val (Z_STR_P (str ));
1653
1664
}
1665
+
1666
+ memcpy (Z_STRVAL_P (str ), ZSTR_VAL (tmp ), new_len );
1667
+ zend_string_release_ex (tmp , 0 );
1654
1668
1655
- // Buffer offset
1656
- int k = 0 ;
1657
- // Source offset
1658
- int i = 0 ;
1659
- char * buffer = emalloc (Z_STRLEN_P (str ) + string_len - 1 ); // -1 as we replace a byte
1660
- char * source = Z_STRVAL_P (str );
1661
- // Append bytes from the source string to the buffer until the offset is reached
1662
- while (i < offset ) {
1663
- buffer [k ] = source [i ];
1664
- i ++ ;
1665
- k ++ ;
1666
- }
1667
- i ++ ; // Skip byte being replaced
1668
- // If not an empty string then append all the bytes from the value to the buffer
1669
- if (string_len > 0 ) {
1670
- int j = 0 ;
1671
- while (string_value [j ] != '\0' ) {
1672
- buffer [k ] = string_value [j ];
1673
- j ++ ;
1674
- k ++ ;
1675
- }
1676
- }
1677
- // Add remaining bytes from the source string.
1678
- while (source [i ] != '\0' ) {
1679
- buffer [k ] = source [i ];
1680
- i ++ ;
1681
- k ++ ;
1682
- }
1683
- // Append NUL byte to make a valid C string.
1684
- buffer [k ] = '\0' ;
1685
- ZVAL_NEW_STR (str , zend_string_init (buffer , Z_STRLEN_P (str ) + string_len - 1 , 0 ));
1686
1669
if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
1687
- ZVAL_INTERNED_STR (EX_VAR (opline -> result .var ), zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P (str ), 0 ));
1670
+ ZVAL_STR (EX_VAR (opline -> result .var ), zend_string_init (Z_STRVAL_P (str ), Z_STRLEN_P (str ), 0 ));
1688
1671
}
1689
-
1690
- efree (buffer );
1691
1672
}
1692
1673
1693
1674
static zend_property_info * zend_get_prop_not_accepting_double (zend_reference * ref )
0 commit comments