@@ -507,24 +507,24 @@ static void php_session_save_current_state(bool write)
507507 IF_SESSION_VARS () {
508508 zval * handler_function = & PS (mod_user_names ).ps_write ;
509509 if (PS (mod_data ) || PS (mod_user_implemented )) {
510- zend_string * val ;
511-
512- val = php_session_encode ();
513- if (val ) {
514- if (PS (lazy_write ) && PS (session_vars )
515- && PS (mod )-> s_update_timestamp
516- && PS (mod )-> s_update_timestamp != php_session_update_timestamp
517- && zend_string_equals (val , PS (session_vars ))
518- ) {
519- ret = PS (mod )-> s_update_timestamp (& PS (mod_data ), PS (id ), val , PS (gc_maxlifetime ));
520- handler_function = & PS (mod_user_names ).ps_update_timestamp ;
521- } else {
522- ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), val , PS (gc_maxlifetime ));
523- }
524- zend_string_release_ex (val , false);
510+ zend_string * val = php_session_encode ();
511+ /* Not being able to encode the session data means there is some kind of issue that prevents a write
512+ * (e.g. a key containing the '|' character with the default serialization) */
513+ if (UNEXPECTED (val == NULL )) {
514+ return ;
515+ }
516+
517+ if (PS (lazy_write ) && PS (session_vars )
518+ && PS (mod )-> s_update_timestamp
519+ && PS (mod )-> s_update_timestamp != php_session_update_timestamp
520+ && zend_string_equals (val , PS (session_vars ))
521+ ) {
522+ ret = PS (mod )-> s_update_timestamp (& PS (mod_data ), PS (id ), val , PS (gc_maxlifetime ));
523+ handler_function = & PS (mod_user_names ).ps_update_timestamp ;
525524 } else {
526- ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), ZSTR_EMPTY_ALLOC () , PS (gc_maxlifetime ));
525+ ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), val , PS (gc_maxlifetime ));
527526 }
527+ zend_string_release_ex (val , false);
528528 }
529529
530530 if ((ret == FAILURE ) && !EG (exception )) {
@@ -929,7 +929,7 @@ PS_SERIALIZER_ENCODE_FUNC(php_serialize)
929929 php_var_serialize (& buf , Z_REFVAL (PS (http_session_vars )), & var_hash );
930930 PHP_VAR_SERIALIZE_DESTROY (var_hash );
931931 }
932- return buf . s ;
932+ return smart_str_extract ( & buf ) ;
933933}
934934
935935PS_SERIALIZER_DECODE_FUNC (php_serialize )
@@ -980,11 +980,9 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary)
980980 smart_str_append (& buf , key );
981981 php_var_serialize (& buf , struc , & var_hash );
982982 );
983-
984- smart_str_0 (& buf );
985983 PHP_VAR_SERIALIZE_DESTROY (var_hash );
986984
987- return buf . s ;
985+ return smart_str_extract ( & buf ) ;
988986}
989987
990988PS_SERIALIZER_DECODE_FUNC (php_binary )
@@ -1038,7 +1036,6 @@ PS_SERIALIZER_ENCODE_FUNC(php)
10381036 PS_ENCODE_LOOP (
10391037 smart_str_append (& buf , key );
10401038 if (memchr (ZSTR_VAL (key ), PS_DELIMITER , ZSTR_LEN (key ))) {
1041- PHP_VAR_SERIALIZE_DESTROY (var_hash );
10421039 smart_str_free (& buf );
10431040 fail = true;
10441041 php_error_docref (NULL , E_WARNING , "Failed to write session data. Data contains invalid key \"%s\"" , ZSTR_VAL (key ));
@@ -1047,15 +1044,15 @@ PS_SERIALIZER_ENCODE_FUNC(php)
10471044 smart_str_appendc (& buf , PS_DELIMITER );
10481045 php_var_serialize (& buf , struc , & var_hash );
10491046 );
1047+ PHP_VAR_SERIALIZE_DESTROY (var_hash );
10501048
10511049 if (fail ) {
10521050 return NULL ;
10531051 }
10541052
1055- smart_str_0 (& buf );
1053+ zend_string * encoded = smart_str_extract (& buf );
10561054
1057- PHP_VAR_SERIALIZE_DESTROY (var_hash );
1058- return buf .s ;
1055+ return encoded ;
10591056}
10601057
10611058PS_SERIALIZER_DECODE_FUNC (php )
@@ -2280,7 +2277,6 @@ PHP_FUNCTION(session_id)
22802277PHP_FUNCTION (session_regenerate_id )
22812278{
22822279 bool del_ses = false;
2283- zend_string * data ;
22842280
22852281 if (zend_parse_parameters (ZEND_NUM_ARGS (), "|b" , & del_ses ) == FAILURE ) {
22862282 RETURN_THROWS ();
@@ -2307,14 +2303,17 @@ PHP_FUNCTION(session_regenerate_id)
23072303 RETURN_FALSE ;
23082304 }
23092305 } else {
2310- zend_result ret ;
2311- data = php_session_encode ();
2312- if (data ) {
2313- ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), data , PS (gc_maxlifetime ));
2314- zend_string_release_ex (data , false);
2315- } else {
2316- ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), ZSTR_EMPTY_ALLOC (), PS (gc_maxlifetime ));
2306+ zend_string * old_session_data = php_session_encode ();
2307+ /* If we have no data we must destroy the related session ID */
2308+ if (UNEXPECTED (old_session_data == NULL )) {
2309+ PS (mod )-> s_close (& PS (mod_data ));
2310+ PS (session_status ) = php_session_none ;
2311+ RETURN_FALSE ;
23172312 }
2313+
2314+ zend_result ret = PS (mod )-> s_write (& PS (mod_data ), PS (id ), old_session_data , PS (gc_maxlifetime ));
2315+ zend_string_release_ex (old_session_data , false);
2316+
23182317 if (ret == FAILURE ) {
23192318 PS (mod )-> s_close (& PS (mod_data ));
23202319 PS (session_status ) = php_session_none ;
@@ -2368,6 +2367,7 @@ PHP_FUNCTION(session_regenerate_id)
23682367 // TODO warn that ID cannot be verified? else { }
23692368 }
23702369 /* Read is required to make new session data at this point. */
2370+ zend_string * data = NULL ;
23712371 if (PS (mod )-> s_read (& PS (mod_data ), PS (id ), & data , PS (gc_maxlifetime )) == FAILURE ) {
23722372 PS (mod )-> s_close (& PS (mod_data ));
23732373 PS (session_status ) = php_session_none ;
0 commit comments