rfc:not_serializable

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:not_serializable [2023/11/26 17:42] maxsemrfc:not_serializable [2023/12/10 12:31] (current) maxsem
Line 1: Line 1:
 ====== PHP RFC: #[NotSerializable] ====== ====== PHP RFC: #[NotSerializable] ======
   * Version: 1.0   * Version: 1.0
-  * Date: 20123-11-26+  * Date: 2023-11-26
   * Author: Max Semenik, maxsem.wiki@gmail.com   * Author: Max Semenik, maxsem.wiki@gmail.com
-  * Status: Draft+  * Status: Under discussion
   * First Published at: http://wiki.php.net/rfc/not_serializable   * First Published at: http://wiki.php.net/rfc/not_serializable
  
 ===== Introduction ===== ===== Introduction =====
-Some classes aren't supposed to be serialized. Examples include closures, various connections like ''PDO'', etc. Currently, while PHP internal classes have a nice way of preventing being serialized/deserialized, userspace doesn't. I'm proposing to make them equal.+Some classes aren't supposed to be serialized. Currently, while PHP internal classes have a nice way of preventing being serialized/unserialized, userspace doesn't. I'm proposing to make them equal.
  
-Compare the internals slapping ''ce_flags |= ZEND_ACC_NOT_SERIALIZABLE'' to userspace doing something like this:+Compare the internals simply slapping ''ce_flags |= ZEND_ACC_NOT_SERIALIZABLE'' to userspace having to do something like this:
  
 <code php> <code php>
 class MyClass class MyClass
 { {
-    public function __sleep() // Wait, what it'signature is supposed to be? Does it matter?+    public function __sleep() // Wait, what its signature is supposed to be? Does it matter?
     {     {
         throw new Exception('This class must not be serialized');         throw new Exception('This class must not be serialized');
Line 26: Line 26:
 </code> </code>
  
-Not only is this method bulky, it also lacks a way for various code analysers to detect attempts to serialize such classes. If courselinters may introduce their own attributes/annotations to catch such mistakes; however various linters +Not only is this method bulky, it's also less readable. It also lacks a way to indicate the intention to various code analysers so that they could detect attempts to serialize such classes
 + 
 +===== Analysis ===== 
 +As of the time I'm writing this, there are 94 uses of ''@not-serializable'' in php-src. Examples include: 
 +  * Closures 
 +  * Various connections like ''PDO'', etc. 
 +  * Reflection 
 + 
 +What could userspace use this for? 
 +  * Wrappers for all the above. Imagine a PDO wrapper that creates connections on demand. If the connection hasn't been established yetits serialization will succeed, which results in unpredictable behavior. 
 +  * Secret information that shouldn't be accidentally exfiltrated by being serialized. 
 +  * Security-sensitive classes that are unsafe to unserialize with arbitrary data ([[https://github.com/wikimedia/mediawiki-libs-ScopedCallback/blob/master/src/ScopedCallback.php|example in the wild]]).
  
 ===== Proposal ===== ===== Proposal =====
-Introduce new attribute that would expose this functionality to userspace.+Introduce new attribute that would expose this functionality to userspace.
  
 <code php> <code php>
Line 40: Line 51:
 </code> </code>
  
-This change requires no changes to the engine whatsoever, all functionality is already present - it merely gets exposed.+The non-serializable flag is inherited by descendants: 
 + 
 +<code php> 
 +class MyOtherClass extends MyClass 
 +
 +
 + 
 +serialize(new MyOtherClass()); // Exception: Serialization of 'MyOtherClass' is not allowed 
 +</code> 
 + 
 +The above requires no changes to the engine whatsoever, all functionality is already present - it merely gets exposed to userspace. 
 + 
 +This feature will be exposed to reflection by the following additions to ReflectionClass: 
 + 
 +<code php> 
 +public const int IS_NOT_SERIALIZABLE = ZEND_ACC_NOT_SERIALIZABLE; 
 + 
 +public function isSerializable(): bool {} 
 +</code>
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
rfc/not_serializable.1701020541.txt.gz · Last modified: 2023/11/26 17:42 by maxsem