Skip to content

Commit cc9a8ee

Browse files
committed
MFH:
- Copy custom callback to the child class if any - Prevent overwriting valid parent callbacks when implementing Serializable - Export zend_user_(un)serialize to be available for custom callbacks
1 parent ce2f9bb commit cc9a8ee

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

Zend/zend_compile.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,6 +2780,14 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
27802780
}
27812781

27822782
ce->parent = parent_ce;
2783+
/* Copy serialize/unserialize callbacks */
2784+
if (!ce->serialize) {
2785+
ce->serialize = parent_ce->serialize;
2786+
}
2787+
if (!ce->unserialize) {
2788+
ce->unserialize = parent_ce->unserialize;
2789+
}
2790+
27832791
/* Inherit interfaces */
27842792
zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);
27852793

Zend/zend_interfaces.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
405405
/* }}}*/
406406

407407
/* {{{ zend_user_serialize */
408-
int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
408+
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
409409
{
410410
zend_class_entry * ce = Z_OBJCE_P(object);
411411
zval *retval;
@@ -442,7 +442,7 @@ int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len
442442
/* }}} */
443443

444444
/* {{{ zend_user_unserialize */
445-
int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
445+
ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
446446
{
447447
zval * zdata;
448448

@@ -466,13 +466,17 @@ int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned ch
466466
/* {{{ zend_implement_serializable */
467467
static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
468468
{
469-
if ((class_type->serialize && class_type->serialize != zend_user_serialize)
470-
|| (class_type->unserialize && class_type->unserialize != zend_user_unserialize)
471-
) {
469+
if (class_type->parent
470+
&& (class_type->parent->serialize || class_type->parent->unserialize)
471+
&& !instanceof_function_ex(class_type->parent, zend_ce_serializable, 1 TSRMLS_CC)) {
472472
return FAILURE;
473473
}
474-
class_type->serialize = zend_user_serialize;
475-
class_type->unserialize = zend_user_unserialize;
474+
if (!class_type->serialize) {
475+
class_type->serialize = zend_user_serialize;
476+
}
477+
if (!class_type->unserialize) {
478+
class_type->unserialize = zend_user_unserialize;
479+
}
476480
return SUCCESS;
477481
}
478482
/* }}}*/

Zend/zend_interfaces.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
6161

6262
ZEND_API void zend_register_interfaces(TSRMLS_D);
6363

64+
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
65+
ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
66+
6467
END_EXTERN_C()
6568

6669
#endif /* ZEND_INTERFACES_H */

0 commit comments

Comments
 (0)