@@ -651,7 +651,7 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /
651651
652652 data -> n += 1 ;
653653
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 ) ) {
655655 return 0 ;
656656 }
657657
@@ -691,32 +691,62 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /
691691
692692static inline void php_var_serialize_long (smart_str * buf , zend_long val ) /* {{{ */
693693{
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 ] = ';' ;
697705}
698706/* }}} */
699707
700708static inline void php_var_serialize_string (smart_str * buf , char * str , size_t len ) /* {{{ */
701709{
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 );
707726}
708727/* }}} */
709728
710729static inline bool php_var_serialize_class_name (smart_str * buf , zval * struc ) /* {{{ */
711730{
731+ char b [32 ], * s , * res ;
732+ size_t l , new_len ;
712733 PHP_CLASS_ATTRIBUTES ;
713734
714735 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 );
720750 PHP_CLEANUP_CLASS_ATTRIBUTES ();
721751 return incomplete_class ;
722752}
@@ -992,11 +1022,19 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
9921022 return ;
9931023
9941024 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+
9971028 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 ] = ';' ;
10001038 return ;
10011039 }
10021040
@@ -1025,9 +1063,9 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
10251063 }
10261064
10271065 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 )));
10291067 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 ) {
10311069 if (!key ) {
10321070 php_var_serialize_long (buf , index );
10331071 } else {
@@ -1052,21 +1090,40 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
10521090 size_t serialized_length ;
10531091
10541092 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 ] = '}' ;
10651120 } else {
10661121 /* Mark this value in the var_hash, to avoid creating references to it. */
10671122 zval * var_idx = zend_hash_index_find (& var_hash -> ht ,
10681123 (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+ }
10701127 smart_str_appendl (buf , "N;" , 2 );
10711128 }
10721129 if (serialized_data ) {
0 commit comments