Skip to content

Commit de88b97

Browse files
committed
[RFC] New attribute #[NotSerializable]
1 parent c5c189d commit de88b97

File tree

6 files changed

+86
-3
lines changed

6 files changed

+86
-3
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
#[NotSerializable]
3+
--FILE--
4+
<?php
5+
6+
#[NotSerializable]
7+
class C {}
8+
9+
try {
10+
serialize(new C());
11+
} catch (Throwable $ex) {
12+
echo $ex->getMessage() . "\n";
13+
}
14+
15+
try {
16+
var_dump(unserialize('O:1:"C":0:{}'));
17+
} catch (Throwable $ex) {
18+
echo $ex->getMessage() . "\n";
19+
}
20+
21+
--EXPECTF--
22+
Serialization of 'C' is not allowed
23+
Unserialization of 'C' is not allowed

Zend/zend_attributes.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ ZEND_API zend_class_entry *zend_ce_allow_dynamic_properties;
3030
ZEND_API zend_class_entry *zend_ce_sensitive_parameter;
3131
ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value;
3232
ZEND_API zend_class_entry *zend_ce_override;
33+
ZEND_API zend_class_entry *zend_ce_not_serializable;
3334

3435
static zend_object_handlers attributes_object_handlers_sensitive_parameter_value;
3536

@@ -80,6 +81,19 @@ static void validate_allow_dynamic_properties(
8081
scope->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;
8182
}
8283

84+
static void validate_not_serializable(
85+
zend_attribute *attr, uint32_t target, zend_class_entry *scope)
86+
{
87+
if (scope->ce_flags & ZEND_ACC_TRAIT) {
88+
zend_error_noreturn(E_ERROR, "Cannot apply #[NotSerializable] to trait");
89+
}
90+
if (scope->ce_flags & ZEND_ACC_INTERFACE) {
91+
zend_error_noreturn(E_ERROR, "Cannot apply #[NotSerializable] to interface");
92+
}
93+
94+
scope->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE;
95+
}
96+
8397
ZEND_METHOD(Attribute, __construct)
8498
{
8599
zend_long flags = ZEND_ATTRIBUTE_TARGET_ALL;
@@ -132,6 +146,11 @@ ZEND_METHOD(SensitiveParameterValue, __debugInfo)
132146
RETURN_EMPTY_ARRAY();
133147
}
134148

149+
ZEND_METHOD(NotSerializable, __construct)
150+
{
151+
ZEND_PARSE_PARAMETERS_NONE();
152+
}
153+
135154
static HashTable *attributes_sensitive_parameter_value_get_properties_for(zend_object *zobj, zend_prop_purpose purpose)
136155
{
137156
return NULL;
@@ -380,6 +399,10 @@ void zend_register_attribute_ce(void)
380399

381400
zend_ce_override = register_class_Override();
382401
zend_mark_internal_attribute(zend_ce_override);
402+
403+
zend_ce_not_serializable = register_class_NotSerializable();
404+
attr = zend_mark_internal_attribute(zend_ce_not_serializable);
405+
attr->validator = validate_not_serializable;
383406
}
384407

385408
void zend_attributes_shutdown(void)

Zend/zend_attributes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern ZEND_API zend_class_entry *zend_ce_allow_dynamic_properties;
4444
extern ZEND_API zend_class_entry *zend_ce_sensitive_parameter;
4545
extern ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value;
4646
extern ZEND_API zend_class_entry *zend_ce_override;
47+
extern ZEND_API zend_class_entry *zend_ce_not_serializable;
4748

4849
typedef struct {
4950
zend_string *name;

Zend/zend_attributes.stub.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,12 @@ final class Override
7171
{
7272
public function __construct() {}
7373
}
74+
75+
/**
76+
* @strict-properties
77+
*/
78+
#[Attribute(Attribute::TARGET_CLASS)]
79+
final class NotSerializable
80+
{
81+
public function __construct() {}
82+
}

Zend/zend_attributes_arginfo.h

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/tests/serialize/ref_to_failed_serialize.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ References to objects for which Serializable::serialize() returned NULL should u
33
--FILE--
44
<?php
55

6-
class NotSerializable implements Serializable {
6+
class MyNotSerializable implements Serializable {
77
public function serialize() {
88
return null;
99
}
@@ -12,7 +12,7 @@ class NotSerializable implements Serializable {
1212
}
1313
}
1414

15-
$obj = new NotSerializable();
15+
$obj = new MyNotSerializable();
1616
$data = [$obj, $obj];
1717
var_dump($s = serialize($data));
1818
var_dump(unserialize($s));

0 commit comments

Comments
 (0)