@@ -651,7 +651,7 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /
651
651
652
652
data -> n += 1 ;
653
653
654
- if (!is_ref && Z_TYPE_P (var ) != IS_OBJECT ) {
654
+ if (!is_ref && ( Z_TYPE_P (var ) != IS_OBJECT || Z_REFCOUNT_P ( var ) == 1 ) ) {
655
655
return 0 ;
656
656
}
657
657
@@ -691,32 +691,62 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /
691
691
692
692
static inline void php_var_serialize_long (smart_str * buf , zend_long val ) /* {{{ */
693
693
{
694
- smart_str_appendl (buf , "i:" , 2 );
695
- smart_str_append_long (buf , val );
696
- smart_str_appendc (buf , ';' );
694
+ char b [32 ];
695
+ char * s = zend_print_long_to_buf (b + sizeof (b ) - 1 , val );
696
+ size_t l = b + sizeof (b ) - 1 - s ;
697
+ size_t new_len = smart_str_alloc (buf , 2 + l + 1 , 0 );
698
+ char * res = ZSTR_VAL (buf -> s ) + ZSTR_LEN (buf -> s );
699
+
700
+ ZSTR_LEN (buf -> s ) = new_len ;
701
+ memcpy (res , "i:" , 2 );
702
+ res += 2 ;
703
+ memcpy (res , s , l );
704
+ res [l ] = ';' ;
697
705
}
698
706
/* }}} */
699
707
700
708
static inline void php_var_serialize_string (smart_str * buf , char * str , size_t len ) /* {{{ */
701
709
{
702
- smart_str_appendl (buf , "s:" , 2 );
703
- smart_str_append_unsigned (buf , len );
704
- smart_str_appendl (buf , ":\"" , 2 );
705
- smart_str_appendl (buf , str , len );
706
- smart_str_appendl (buf , "\";" , 2 );
710
+ char b [32 ];
711
+ char * s = zend_print_long_to_buf (b + sizeof (b ) - 1 , len );
712
+ size_t l = b + sizeof (b ) - 1 - s ;
713
+ size_t new_len = smart_str_alloc (buf , 2 + l + 2 + len + 2 , 0 );
714
+ char * res = ZSTR_VAL (buf -> s ) + ZSTR_LEN (buf -> s );
715
+
716
+ ZSTR_LEN (buf -> s ) = new_len ;
717
+ memcpy (res , "s:" , 2 );
718
+ res += 2 ;
719
+ memcpy (res , s , l );
720
+ res += l ;
721
+ memcpy (res , ":\"" , 2 );
722
+ res += 2 ;
723
+ memcpy (res , str , len );
724
+ res += len ;
725
+ memcpy (res , "\";" , 2 );
707
726
}
708
727
/* }}} */
709
728
710
729
static inline bool php_var_serialize_class_name (smart_str * buf , zval * struc ) /* {{{ */
711
730
{
731
+ char b [32 ], * s , * res ;
732
+ size_t l , new_len ;
712
733
PHP_CLASS_ATTRIBUTES ;
713
734
714
735
PHP_SET_CLASS_ATTRIBUTES (struc );
715
- smart_str_appendl (buf , "O:" , 2 );
716
- smart_str_append_unsigned (buf , ZSTR_LEN (class_name ));
717
- smart_str_appendl (buf , ":\"" , 2 );
718
- smart_str_append (buf , class_name );
719
- smart_str_appendl (buf , "\":" , 2 );
736
+ s = zend_print_long_to_buf (b + sizeof (b ) - 1 , ZSTR_LEN (class_name ));
737
+ l = b + sizeof (b ) - 1 - s ;
738
+ new_len = smart_str_alloc (buf , 2 + l + 2 + ZSTR_LEN (class_name ) + 2 , 0 );
739
+ res = ZSTR_VAL (buf -> s ) + ZSTR_LEN (buf -> s );
740
+ ZSTR_LEN (buf -> s ) = new_len ;
741
+ memcpy (res , "O:" , 2 );
742
+ res += 2 ;
743
+ memcpy (res , s , l );
744
+ res += l ;
745
+ memcpy (res , ":\"" , 2 );
746
+ res += 2 ;
747
+ memcpy (res , ZSTR_VAL (class_name ), ZSTR_LEN (class_name ));
748
+ res += ZSTR_LEN (class_name );
749
+ memcpy (res , "\":" , 2 );
720
750
PHP_CLEANUP_CLASS_ATTRIBUTES ();
721
751
return incomplete_class ;
722
752
}
@@ -992,11 +1022,19 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
992
1022
return ;
993
1023
994
1024
case IS_DOUBLE : {
995
- char tmp_str [PHP_DOUBLE_MAX_LENGTH ];
996
- smart_str_appendl (buf , "d:" , 2 );
1025
+ char tmp_str [PHP_DOUBLE_MAX_LENGTH ], * res ;
1026
+ size_t len , new_len ;
1027
+
997
1028
php_gcvt (Z_DVAL_P (struc ), (int )PG (serialize_precision ), '.' , 'E' , tmp_str );
998
- smart_str_appends (buf , tmp_str );
999
- smart_str_appendc (buf , ';' );
1029
+ len = strlen (tmp_str );
1030
+ new_len = smart_str_alloc (buf , 2 + len + 1 , 0 );
1031
+ res = ZSTR_VAL (buf -> s ) + ZSTR_LEN (buf -> s );
1032
+ ZSTR_LEN (buf -> s ) = new_len ;
1033
+
1034
+ memcpy (res , "d:" , 2 );
1035
+ res += 2 ;
1036
+ memcpy (res , tmp_str , len );
1037
+ res [len ] = ';' ;
1000
1038
return ;
1001
1039
}
1002
1040
@@ -1025,9 +1063,9 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
1025
1063
}
1026
1064
1027
1065
php_var_serialize_class_name (buf , & obj );
1028
- smart_str_append_unsigned (buf , zend_array_count (Z_ARRVAL (retval )));
1066
+ smart_str_append_unsigned (buf , zend_hash_num_elements (Z_ARRVAL (retval )));
1029
1067
smart_str_appendl (buf , ":{" , 2 );
1030
- ZEND_HASH_FOREACH_KEY_VAL_IND (Z_ARRVAL (retval ), index , key , data ) {
1068
+ ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL (retval ), index , key , data ) {
1031
1069
if (!key ) {
1032
1070
php_var_serialize_long (buf , index );
1033
1071
} else {
@@ -1052,21 +1090,40 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
1052
1090
size_t serialized_length ;
1053
1091
1054
1092
if (ce -> serialize (struc , & serialized_data , & serialized_length , (zend_serialize_data * )var_hash ) == SUCCESS ) {
1055
- smart_str_appendl (buf , "C:" , 2 );
1056
- smart_str_append_unsigned (buf , ZSTR_LEN (Z_OBJCE_P (struc )-> name ));
1057
- smart_str_appendl (buf , ":\"" , 2 );
1058
- smart_str_append (buf , Z_OBJCE_P (struc )-> name );
1059
- smart_str_appendl (buf , "\":" , 2 );
1060
-
1061
- smart_str_append_unsigned (buf , serialized_length );
1062
- smart_str_appendl (buf , ":{" , 2 );
1063
- smart_str_appendl (buf , (char * ) serialized_data , serialized_length );
1064
- smart_str_appendc (buf , '}' );
1093
+ char b1 [32 ], b2 [32 ], * s1 , * s2 , * res ;
1094
+ size_t l1 , l2 , new_len ;
1095
+
1096
+ s1 = zend_print_long_to_buf (b1 + sizeof (b1 ) - 1 , ZSTR_LEN (Z_OBJCE_P (struc )-> name ));
1097
+ l1 = b1 + sizeof (b1 ) - 1 - s1 ;
1098
+ s2 = zend_print_long_to_buf (b2 + sizeof (b2 ) - 1 , serialized_length );
1099
+ l2 = b2 + sizeof (b2 ) - 1 - s2 ;
1100
+ new_len = smart_str_alloc (buf , 2 + l1 + 2 + ZSTR_LEN (Z_OBJCE_P (struc )-> name ) + 2 + l2 + 2 + serialized_length + 1 , 0 );
1101
+ res = ZSTR_VAL (buf -> s ) + ZSTR_LEN (buf -> s );
1102
+ ZSTR_LEN (buf -> s ) = new_len ;
1103
+ memcpy (res , "C:" , 2 );
1104
+ res += 2 ;
1105
+ memcpy (res , s1 , l1 );
1106
+ res += l1 ;
1107
+ memcpy (res , ":\"" , 2 );
1108
+ res += 2 ;
1109
+ memcpy (res , ZSTR_VAL (Z_OBJCE_P (struc )-> name ), ZSTR_LEN (Z_OBJCE_P (struc )-> name ));
1110
+ res += ZSTR_LEN (Z_OBJCE_P (struc )-> name );
1111
+ memcpy (res , "\":" , 2 );
1112
+ res += 2 ;
1113
+
1114
+ memcpy (res , s2 , l2 );
1115
+ res += l2 ;
1116
+ memcpy (res , ":{" , 2 );
1117
+ res += 2 ;
1118
+ memcpy (res , (char * ) serialized_data , serialized_length );
1119
+ res [serialized_length ] = '}' ;
1065
1120
} else {
1066
1121
/* Mark this value in the var_hash, to avoid creating references to it. */
1067
1122
zval * var_idx = zend_hash_index_find (& var_hash -> ht ,
1068
1123
(zend_ulong ) (zend_uintptr_t ) Z_COUNTED_P (struc ));
1069
- ZVAL_LONG (var_idx , -1 );
1124
+ if (var_idx ) {
1125
+ ZVAL_LONG (var_idx , -1 );
1126
+ }
1070
1127
smart_str_appendl (buf , "N;" , 2 );
1071
1128
}
1072
1129
if (serialized_data ) {
0 commit comments