Skip to content
Closed
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
11 changes: 7 additions & 4 deletions src/php7/igbinary.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,16 @@ static zend_always_inline void zval_ptr_dtor_str(zval *zval_ptr)

#if PHP_VERSION_ID >= 70400
# ifdef ZEND_ACC_NOT_SERIALIZABLE
#define IGBINARY_IS_NOT_SERIALIZABLE(ce) UNEXPECTED((ce)->ce_flags & (ZEND_ACC_NOT_SERIALIZABLE | ZEND_ACC_ANON_CLASS))
#define IGBINARY_IS_NOT_SERIALIZABLE_COMMON(ce) UNEXPECTED((ce)->ce_flags & (ZEND_ACC_NOT_SERIALIZABLE | ZEND_ACC_ANON_CLASS))
# else
#define IGBINARY_IS_NOT_SERIALIZABLE(ce) UNEXPECTED(((ce)->ce_flags & (ZEND_ACC_ANON_CLASS)) || (ce)->serialize == zend_class_serialize_deny)
#define IGBINARY_IS_NOT_SERIALIZABLE_COMMON(ce) UNEXPECTED((ce)->ce_flags & (ZEND_ACC_ANON_CLASS))
# endif
#define IGBINARY_IS_NOT_SERIALIZABLE(ce) UNEXPECTED(IGBINARY_IS_NOT_SERIALIZABLE_COMMON(ce) || (ce)->serialize == zend_class_serialize_deny)
#define IGBINARY_IS_NOT_UNSERIALIZABLE(ce) UNEXPECTED(IGBINARY_IS_NOT_SERIALIZABLE_COMMON(ce) || (ce)->unserialize == zend_class_unserialize_deny)
#else
// Because '__serialize' is not available prior to 7.4, this check is redundant.
#define IGBINARY_IS_NOT_SERIALIZABLE(ce) (0)
#define IGBINARY_IS_NOT_UNSERIALIZABLE(ce) (0)
#endif


Expand Down Expand Up @@ -2864,7 +2867,7 @@ static ZEND_COLD int igbinary_unserialize_object_ser(struct igbinary_unserialize
return 1;
}

if (IGBINARY_IS_NOT_SERIALIZABLE(ce)) {
if (IGBINARY_IS_NOT_UNSERIALIZABLE(ce)) {
zend_throw_exception_ex(NULL, 0, "Unserialization of '%s' is not allowed", ZSTR_VAL(ce->name));
return 1;
}
Expand Down Expand Up @@ -3053,7 +3056,7 @@ inline static int igbinary_unserialize_object(struct igbinary_unserialize_data *
}
} while (0);

if (IGBINARY_IS_NOT_SERIALIZABLE(ce)) {
if (IGBINARY_IS_NOT_UNSERIALIZABLE(ce)) {
zend_throw_exception_ex(NULL, 0, "Unserialization of '%s' is not allowed", ZSTR_VAL(ce->name));
zend_string_release(class_name);
return 1;
Expand Down
93 changes: 93 additions & 0 deletions tests/igbinary_095.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
--TEST--
Test handling php 8.1 readonly properties
--SKIPIF--
<?php if (PHP_VERSION_ID < 80100) { echo "skip readonly properties require php 8.1+\n"; } ?>
--FILE--
<?php
class X {
public readonly mixed $var;

public function __construct(
public readonly int $a,
private readonly ArrayAccess&Countable $intersection,
protected readonly ?string $default = null,
) {
$this->var = $intersection;
}
}

class Y {
public readonly mixed $var;

public function __construct(
public readonly int $a,
private readonly ArrayAccess&Countable $intersection,
protected readonly ?string $default = null,
) {
$this->var = $intersection;
}

public function __serialize(): array {
return [
'a' => $this->a,
'intersection' => $this->intersection,
'default' => $this->default,
'var' => $this->var,
];
}
public function __unserialize(array $data) {
[
'a' => $this->a,
'intersection' => $this->intersection,
'default' => $this->default,
'var' => $this->var,
] = $data;
}
}

$ser = igbinary_serialize(new X(1, new ArrayObject()));
echo urlencode($ser), "\n";
var_dump(igbinary_unserialize($ser));
$ser = igbinary_serialize(new Y(1, new ArrayObject()));
echo urlencode($ser), "\n";
var_dump(igbinary_unserialize($ser));
?>
--EXPECT--
%00%00%00%02%17%01X%14%04%11%03var%17%0BArrayObject%14%04%06%00%06%00%06%01%14%00%06%02%14%00%06%03%00%11%01a%06%01%11%0F%00X%00intersection%22%01%11%0A%00%2A%00default%00
object(X)#1 (4) {
["var"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["a"]=>
int(1)
["intersection":"X":private]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["default":protected]=>
NULL
}
%00%00%00%02%17%01Y%14%04%11%01a%06%01%11%0Cintersection%17%0BArrayObject%14%04%06%00%06%00%06%01%14%00%06%02%14%00%06%03%00%11%07default%00%11%03var%22%01
object(Y)#1 (4) {
["var"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["a"]=>
int(1)
["intersection":"Y":private]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
["default":protected]=>
NULL
}