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
@@ -365,23 +366,35 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable
365366}
366367/* }}} */
367368
368- 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 ) /* {{{ */ {
369+ static inline void msgpack_serialize_object (smart_str * buf , zval * val , HashTable * var_hash ) /* {{{ */ {
369370 int res ;
370371 zval retval , fname ;
371372 zval * val_noref ;
372373 zend_class_entry * ce = NULL ;
373374 zend_string * sleep_zstring ;
375+ PHP_CLASS_ATTRIBUTES ;
374376
375377 if (UNEXPECTED (Z_TYPE_P (val ) == IS_REFERENCE )) {
376378 val_noref = Z_REFVAL_P (val );
377379 } else {
378380 val_noref = val ;
379381 }
380382
383+ PHP_SET_CLASS_ATTRIBUTES (val_noref );
384+
381385 if (Z_OBJCE_P (val_noref )) {
382386 ce = Z_OBJCE_P (val_noref );
383387 }
384388
389+ #if PHP_VERSION_ID >= 80100
390+ if (ce && (ce -> ce_flags & ZEND_ACC_NOT_SERIALIZABLE )) {
391+ msgpack_pack_nil (buf );
392+ zend_throw_exception_ex (NULL , 0 , "Serialization of '%s' is not allowed" , ZSTR_VAL (ce -> name ));
393+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
394+ return ;
395+ }
396+ #endif
397+
385398 if (ce && ce -> serialize != NULL ) {
386399 unsigned char * serialized_data = NULL ;
387400 size_t serialized_length ;
@@ -403,25 +416,27 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
403416 if (serialized_data ) {
404417 efree (serialized_data );
405418 }
419+
420+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
406421 return ;
407422 }
408423
409424 sleep_zstring = zend_string_init ("__sleep" , sizeof ("__sleep" ) - 1 , 0 );
410425 ZVAL_STR (& fname , sleep_zstring );
411426
412- if (ce && ce != PHP_IC_ENTRY &&
413- zend_hash_exists (& ce -> function_table , sleep_zstring )) {
427+ if (!incomplete_class && ce && zend_hash_exists (& ce -> function_table , sleep_zstring )) {
414428 if ((res = call_user_function (CG (function_table ), val_noref , & fname , & retval , 0 , 0 )) == SUCCESS ) {
415429
416430 if (EG (exception )) {
417431 zval_ptr_dtor (& retval );
418432 zval_ptr_dtor (& fname );
433+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
419434 return ;
420435 }
421436 if (Z_TYPE (retval ) == IS_ARRAY ) {
422437 msgpack_serialize_class (
423438 buf , val_noref , & retval , var_hash ,
424- class_name , name_len , incomplete_class );
439+ class_name -> val , class_name -> len , incomplete_class );
425440 } else {
426441 MSGPACK_NOTICE (
427442 "[msgpack] (%s) __sleep should return an array only "
@@ -431,14 +446,17 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
431446 }
432447 zval_ptr_dtor (& retval );
433448 zval_ptr_dtor (& fname );
449+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
434450 return ;
435451 }
436452 }
437453
438454 zval_ptr_dtor (& fname );
439455 msgpack_serialize_array (
440456 buf , val , var_hash , 1 ,
441- class_name , name_len , incomplete_class );
457+ class_name -> val , class_name -> len , incomplete_class );
458+
459+ PHP_CLEANUP_CLASS_ATTRIBUTES ();
442460}
443461/* }}} */
444462
@@ -516,14 +534,7 @@ void msgpack_serialize_zval(smart_str *buf, zval *val, HashTable *var_hash) /* {
516534 msgpack_serialize_array (buf , val , var_hash , 0 , NULL , 0 , 0 );
517535 break ;
518536 case IS_OBJECT :
519- {
520- PHP_CLASS_ATTRIBUTES ;
521- PHP_SET_CLASS_ATTRIBUTES (val_noref );
522-
523- msgpack_serialize_object (buf , val , var_hash , ZSTR_VAL (class_name ), ZSTR_LEN (class_name ), incomplete_class );
524-
525- PHP_CLEANUP_CLASS_ATTRIBUTES ();
526- }
537+ msgpack_serialize_object (buf , val , var_hash );
527538 break ;
528539 default :
529540 MSGPACK_WARNING (
0 commit comments