Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions msgpack_unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,40 @@ int msgpack_unserialize_map_item(msgpack_unpack_data *unpack, zval **container,
return 0;
}

/* found Enum does not contain specified case */
zend_class_constant *constant_ptr = zend_hash_find_ptr(
&ce->constants_table,
Z_STR_P(val));
if (constant_ptr == NULL) {
MSGPACK_WARNING(
"[msgpack] (%s) Enum case %s does not exist in Enum %s",
__FUNCTION__, Z_STRVAL_P(val), ZSTR_VAL(ce->name));

MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val);
return 0;
}

/* found Enum property is not a case but a constant */
zval *constant = &constant_ptr->value;
if (Z_TYPE_P(constant) == IS_OBJECT) {
zend_object *obj = Z_OBJ_P(constant);
if (!instanceof_function(obj->ce, ce)) {
MSGPACK_WARNING(
"[msgpack] (%s) %s::%s is not an Enum case but a constant",
__FUNCTION__, ZSTR_VAL(ce->name), Z_STRVAL_P(val));

MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val);
return 0;
}
} else {
MSGPACK_WARNING(
"[msgpack] (%s) %s::%s is not an Enum case but a constant",
__FUNCTION__, ZSTR_VAL(ce->name), Z_STRVAL_P(val));

MSGPACK_UNSERIALIZE_FINISH_MAP_ITEM(unpack, key, val);
return 0;
}

zend_object *enum_instance = zend_enum_get_case(ce, Z_STR_P(val));
ZVAL_OBJ_COPY(*container, enum_instance);
#endif
Expand Down
28 changes: 28 additions & 0 deletions tests/issue186.1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
Issue #182 (unknown enum case)
--SKIPIF--
<?php
if (!extension_loaded("msgpack")) {
exit('skip because msgpack extension is missing');
}
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
exit('skip Enum tests in PHP older than 8.1.0');
}
?>
--FILE--
Test
<?php
enum TestEnum
{
case A;
}

$data = file_get_contents(__DIR__.'/issue186.ser.txt');
$unserilized = msgpack_unserialize($data);
?>
OK
--EXPECTF--
Test

Warning: [msgpack] (msgpack_unserialize_map_item) Enum case B does not exist in Enum TestEnum in %s/issue186.1.php on line 9
OK
30 changes: 30 additions & 0 deletions tests/issue186.2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
Issue #182 (unknown enum case)
--SKIPIF--
<?php
if (!extension_loaded("msgpack")) {
exit('skip because msgpack extension is missing');
}
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
exit('skip Enum tests in PHP older than 8.1.0');
}
?>
--FILE--
Test
<?php
enum TestEnum
{
case A;

public const B = 42;
}

$data = file_get_contents(__DIR__.'/issue186.ser.txt');
$unserilized = msgpack_unserialize($data);
?>
OK
--EXPECTF--
Test

Warning: [msgpack] (msgpack_unserialize_map_item) TestEnum::B is not an Enum case but a constant in %s/issue186.2.php on line 11
OK
34 changes: 34 additions & 0 deletions tests/issue186.3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
--TEST--
Issue #182 (unknown enum case)
--SKIPIF--
<?php
if (!extension_loaded("msgpack")) {
exit('skip because msgpack extension is missing');
}
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
exit('skip Enum tests in PHP older than 8.1.0');
}
?>
--FILE--
Test
<?php
enum AnotherEnum {
case C;
}

enum TestEnum
{
case A;

public const B = AnotherEnum::C;
}

$data = file_get_contents(__DIR__.'/issue186.ser.txt');
$unserilized = msgpack_unserialize($data);
?>
OK
--EXPECTF--
Test

Warning: [msgpack] (msgpack_unserialize_map_item) TestEnum::B is not an Enum case but a constant in %s/issue186.3.php on line 15
OK
1 change: 1 addition & 0 deletions tests/issue186.ser.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
‚À¨TestEnum¡B
Loading