-
-
Notifications
You must be signed in to change notification settings - Fork 157
Investigate weird serialization logic #277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1976,7 +1976,7 @@ protected function maybe_unserialize( $original ) { | |||||||||||||||
| return igbinary_unserialize( $original ); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Don't attempt to unserialize data that wasn't serialized going in. | ||||||||||||||||
| // Unserialize data that was serialized | ||||||||||||||||
| if ( $this->is_serialized( $original ) ) { | ||||||||||||||||
| // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize | ||||||||||||||||
| $value = @unserialize( $original ); | ||||||||||||||||
|
|
@@ -2006,17 +2006,13 @@ protected function maybe_serialize( $data ) { | |||||||||||||||
| return igbinary_serialize( $data ); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| if ( is_array( $data ) || is_object( $data ) ) { | ||||||||||||||||
| // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize | ||||||||||||||||
| return serialize( $data ); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Don't serialize data that's already serialized | ||||||||||||||||
| if ( $this->is_serialized( $data, false ) ) { | ||||||||||||||||
| // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize | ||||||||||||||||
| return serialize( $data ); | ||||||||||||||||
| return $data; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| return $data; | ||||||||||||||||
| // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize | ||||||||||||||||
| return serialize( $data ); | ||||||||||||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Always serialize, except if it already was serialized? @naxvog thoughts?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does Redis currently contain double serialized data? If so, what were the use cases?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. <?php
class Naxvog_Test {
private $creation_time;
private $serialization_time;
public $some_prop;
private $some_secret_prop;
public function __construct() {
$this->creation_time = time();
$this->some_secret_prop = 'baz';
$this->some_prop = 'bar';
}
public function __serialize() {
return [
'serialization_time' => time(),
'creation_time' => $this->creation_time,
];
}
public function __unserialize( $data ) {
$this->serialization_time = $data['serialization_time'];
$this->creation_time = $data['creation_time'];
}
}
add_action( 'init', function() {
$a = new Naxvog_Test();
$s = serialize( $a );
#var_dump( $a, $s );
#var_dump( unserialize( $s ) );
if ( isset( $_GET['debug-set'] ) ) {
wp_cache_set( 'naxvog_test_obj1', $a );
wp_cache_set( 'naxvog_test_obj2', $s );
}
if ( isset( $_GET['debug-get'] ) ) {
var_dump( wp_cache_get( 'naxvog_test_obj1' ) );
var_dump( wp_cache_get( 'naxvog_test_obj2' ) );
}
} );
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we check
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather prefer a conversion script running on plugin update resolving such issues but this might be a non trivial approach, would most likely require a LUA script and will take some time (best suited for action scheduler).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't think of any valid way to serialize twice. Sure there might be serialized data within a serialized object but this is expected behaviour. Have to look again but I'm fairly sure that I have not found any double serialized key our docker dev environment. Will have a look on my production redis instance. Should be fairly easy to find.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK found some instances (ran vim searching for
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we simply solve this by running this twice? redis-cache/includes/object-cache.php Lines 1979 to 1985 in fbfc86f
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have to look in the code of those plugins to confirm that this is not intended. If not we should find the cause for this double serialization instead.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Running |
||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| /** | ||||||||||||||||
|
|
@@ -2073,6 +2069,7 @@ protected function is_serialized( $data, $strict = true ) { | |||||||||||||||
| return false; | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| $token = $data[0]; | ||||||||||||||||
|
|
||||||||||||||||
| switch ( $token ) { | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To simplify things we could just flush the cache every time the plugin is updated.
Alternatively we should avoid polluting the options table with version specific entries - a general
roc_versionstoring the last known version would be better. Migrations would only run if the current plugin version is newer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed 👌🏻