22#include "php.h"
33#include "php_ini.h"
44#include "Zend/zend_smart_str.h"
5+ #include "Zend/zend_exceptions.h"
56#include "ext/standard/php_incomplete_class.h"
67#include "ext/standard/php_var.h"
78
@@ -363,23 +364,35 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable
363364}
364365/* }}} */
365366
366- static inline void msgpack_serialize_object (smart_str * buf , zval * val , HashTable * var_hash , char * class_name , uint32_t name_len , zend_bool incomplete_class ) /* {{{ */ {
367+ static inline void msgpack_serialize_object (smart_str * buf , zval * val , HashTable * var_hash ) /* {{{ */ {
367368 int res ;
368369 zval retval , fname ;
369370 zval * val_noref ;
370371 zend_class_entry * ce = NULL ;
371372 zend_string * sleep_zstring ;
373+ PHP_CLASS_ATTRIBUTES ;
372374
373375 if (UNEXPECTED (Z_TYPE_P (val ) == IS_REFERENCE )) {
374376 val_noref = Z_REFVAL_P (val );
375377 } else {
376378 val_noref = val ;
377379 }
378380
381+ PHP_SET_CLASS_ATTRIBUTES (val_noref );
382+
379383 if (Z_OBJCE_P (val_noref )) {
380384 ce = Z_OBJCE_P (val_noref );
381385 }
382386
387+ #if PHP_VERSION_ID >= 80100
388+ if (ce && (ce -> ce_flags & ZEND_ACC_NOT_SERIALIZABLE )) {
389+ msgpack_pack_nil (buf );
390+ zend_throw_exception_ex (NULL , 0 , "Serialization of '%s' is not allowed" , ZSTR_VAL (ce -> name ));
391+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
392+ return ;
393+ }
394+ #endif
395+
383396 if (ce && ce -> serialize != NULL ) {
384397 unsigned char * serialized_data = NULL ;
385398 size_t serialized_length ;
@@ -401,25 +414,27 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
401414 if (serialized_data ) {
402415 efree (serialized_data );
403416 }
417+
418+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
404419 return ;
405420 }
406421
407422 sleep_zstring = zend_string_init ("__sleep" , sizeof ("__sleep" ) - 1 , 0 );
408423 ZVAL_STR (& fname , sleep_zstring );
409424
410- if (ce && ce != PHP_IC_ENTRY &&
411- zend_hash_exists (& ce -> function_table , sleep_zstring )) {
425+ if (!incomplete_class && ce && zend_hash_exists (& ce -> function_table , sleep_zstring )) {
412426 if ((res = call_user_function (CG (function_table ), val_noref , & fname , & retval , 0 , 0 )) == SUCCESS ) {
413427
414428 if (EG (exception )) {
415429 zval_ptr_dtor (& retval );
416430 zval_ptr_dtor (& fname );
431+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
417432 return ;
418433 }
419434 if (Z_TYPE (retval ) == IS_ARRAY ) {
420435 msgpack_serialize_class (
421436 buf , val_noref , & retval , var_hash ,
422- class_name , name_len , incomplete_class );
437+ class_name -> val , class_name -> len , incomplete_class );
423438 } else {
424439 MSGPACK_NOTICE (
425440 "[msgpack] (%s) __sleep should return an array only "
@@ -429,14 +444,17 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
429444 }
430445 zval_ptr_dtor (& retval );
431446 zval_ptr_dtor (& fname );
447+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
432448 return ;
433449 }
434450 }
435451
436452 zval_ptr_dtor (& fname );
437453 msgpack_serialize_array (
438454 buf , val , var_hash , 1 ,
439- class_name , name_len , incomplete_class );
455+ class_name -> val , class_name -> len , incomplete_class );
456+
457+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
440458}
441459/* }}} */
442460
@@ -514,14 +532,7 @@ void msgpack_serialize_zval(smart_str *buf, zval *val, HashTable *var_hash) /* {
514532 msgpack_serialize_array (buf , val , var_hash , 0 , NULL , 0 , 0 );
515533 break ;
516534 case IS_OBJECT :
517- {
518- PHP_CLASS_ATTRIBUTES ;
519- PHP_SET_CLASS_ATTRIBUTES (val_noref );
520-
521- msgpack_serialize_object (buf , val , var_hash , ZSTR_VAL (class_name ), ZSTR_LEN (class_name ), incomplete_class );
522-
523- PHP_CLEANUP_CLASS_ATTRIBUTES ();
524- }
535+ msgpack_serialize_object (buf , val , var_hash );
525536 break ;
526537 default :
527538 MSGPACK_WARNING (
0 commit comments