Skip to content

Commit b285146

Browse files
committed
PHP-7.4 compatibility
1 parent 2fae216 commit b285146

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
@@ -407,11 +407,11 @@ static inline void msgpack_serialize_object(smart_str *buf, zval *val, HashTable
407407
#endif
408408

409409
#if PHP_VERSION_ID >= 70400
410-
if (ce && ce->__serialize) {
410+
if (IS_MAGIC_SERIALIZABLE(ce)) {
411411
zval retval, obj;
412412

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

416416
if (!EG(exception)) {
417417
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
@@ -58,4 +58,43 @@ PHP_MSGPACK_API int php_msgpack_unserialize(
5858
# define OBJ_FOR_PROP(zv) Z_OBJ_P(zv)
5959
#endif
6060

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

0 commit comments

Comments
 (0)