Skip to content

Commit 01d1153

Browse files
committed
PHP-7.4 compatibility
1 parent d302ed7 commit 01d1153

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

msgpack_pack.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,11 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
409409
#endif
410410

411411
#if PHP_VERSION_ID >= 70400
412-
if (ce && ce->__serialize) {
412+
if (IS_MAGIC_SERIALIZABLE(ce)) {
413413
zval retval, obj;
414414

415415
ZVAL_COPY(&obj, val_noref);
416-
zend_call_known_instance_method_with_0_params(Z_OBJCE(obj)->__serialize, Z_OBJ(obj), &retval);
416+
CALL_MAGIC_SERIALIZE(ce, Z_OBJ(obj), &retval);
417417

418418
if (!EG(exception)) {
419419
if (Z_TYPE(retval) == IS_ARRAY) {

msgpack_unpack.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -627,14 +627,13 @@ int msgpack_unserialize_map_item(msgpack_unserialize_data *unpack, zval **contai
627627
msgpack_unserialize_class(container, Z_STR_P(val), 1);
628628
#if PHP_VERSION_ID >= 70400
629629
} else if (Z_TYPE_P(val) == IS_ARRAY) {
630-
if (Z_TYPE_P(*container) == IS_OBJECT && (ce = Z_OBJCE_P(*container)) && ce->__unserialize) {
630+
if (Z_TYPE_P(*container) == IS_OBJECT && IS_MAGIC_SERIALIZABLE((ce = Z_OBJCE_P(*container)))) {
631631
zval param;
632632
ZVAL_COPY(&param, val);
633-
zend_object *prev_exc = EG(exception);
634633

635-
zend_call_known_instance_method_with_1_params(
636-
ce->__unserialize, Z_OBJ_P(*container), NULL, &param);
637-
if (EG(exception) != prev_exc) {
634+
CALL_MAGIC_UNSERIALIZE(ce, Z_OBJ_P(*container), NULL, &param);
635+
636+
if (EG(exception)) {
638637
GC_ADD_FLAGS(Z_OBJ_P(*container), IS_OBJ_DESTRUCTOR_CALLED);
639638
}
640639
zval_ptr_dtor(&param);

php_msgpack.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,43 @@ PHP_MSGPACK_API int php_msgpack_unserialize(
5959
# define OBJ_FOR_PROP(zv) Z_OBJ_P(zv)
6060
#endif
6161

62+
#if PHP_VERSION_ID >= 80000
63+
# define IS_MAGIC_SERIALIZABLE(ce) (ce && ce->__serialize)
64+
# define CALL_MAGIC_SERIALIZE(cep, zop, rvp) zend_call_known_instance_method_with_0_params((cep)->__serialize, zop, rvp)
65+
# define CALL_MAGIC_UNSERIALIZE(cep, zop, rvp, zsdap) zend_call_known_instance_method_with_1_params((cep)->__unserialize, zop, rvp, zsdap)
66+
#elif PHP_VERSION_ID >= 70400
67+
# define IS_MAGIC_SERIALIZABLE(ce) (ce && zend_hash_str_exists(&ce->function_table, ZEND_STRL("__serialize")))
68+
# define CALL_MAGIC_SERIALIZE(cep, zop, rvp) call_magic_serialize_fn(cep, zop, rvp, ZEND_STRL("__serialize"), 0, NULL)
69+
# define CALL_MAGIC_UNSERIALIZE(cep, zop, rvp, zsdap) call_magic_serialize_fn(cep, zop, rvp, ZEND_STRL("__unserialize"), 1, zsdap)
70+
static inline void call_magic_serialize_fn(zend_class_entry *ce, zend_object *object, zval *retval_ptr, const char *fn_str, size_t fn_len, int param_count, zval *params) {
71+
zval retval;
72+
zend_fcall_info fci;
73+
zend_fcall_info_cache fcic;
74+
75+
fci.size = sizeof(fci);
76+
fci.object = object;
77+
fci.retval = retval_ptr ? retval_ptr : &retval;
78+
fci.param_count = param_count;
79+
fci.params = params;
80+
ZVAL_UNDEF(&fci.function_name); /* Unused */
81+
82+
fcic.function_handler = zend_hash_str_find_ptr(&ce->function_table, fn_str, fn_len);
83+
fcic.object = object;
84+
fcic.called_scope = ce;
85+
86+
int result = zend_call_function(&fci, &fcic);
87+
if (UNEXPECTED(result == FAILURE)) {
88+
if (!EG(exception)) {
89+
zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
90+
fcic.function_handler->common.scope ? ZSTR_VAL(fcic.function_handler->common.scope->name) : "",
91+
fcic.function_handler->common.scope ? "::" : "", ZSTR_VAL(fcic.function_handler->common.function_name));
92+
}
93+
}
94+
95+
if (!retval_ptr) {
96+
zval_ptr_dtor(&retval);
97+
}
98+
}
99+
#endif
100+
62101
#endif /* PHP_MSGPACK_H */

0 commit comments

Comments
 (0)