Skip to content

Commit 29a64a7

Browse files
committed
fix #161: Support PHP 8.1's ZEND_ACC_NOT_SERIALIZABLE flag on zend_class_entries
1 parent e285c67 commit 29a64a7

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

msgpack_pack.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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

Comments
 (0)