Skip to content

Commit 48b2b65

Browse files
committed
Revisions: Prevent fatal error in PHP 8+ when saving a post revision with revisioned non-scalar post meta.
Developed in WordPress#10560 Follow-up to [56714]. Props LAPSrj, manhphucofficial, westonruter. See #20299. Fixes #64314. git-svn-id: https://develop.svn.wordpress.org/trunk@61372 602fd350-edb4-49c9-b593-d223f7449a82
1 parent b6f02b8 commit 48b2b65

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/wp-includes/revision.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function wp_save_post_revision( $post_id ) {
187187
$post_has_changed = false;
188188

189189
foreach ( array_keys( _wp_post_revision_fields( $post ) ) as $field ) {
190-
if ( normalize_whitespace( $post->$field ) !== normalize_whitespace( $latest_revision->$field ) ) {
190+
if ( normalize_whitespace( maybe_serialize( $post->$field ) ) !== normalize_whitespace( maybe_serialize( $latest_revision->$field ) ) ) {
191191
$post_has_changed = true;
192192
break;
193193
}

tests/phpunit/tests/post/revisions.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,4 +930,63 @@ static function ( $revisions ) {
930930
'The title of the second revision was incorrect.'
931931
);
932932
}
933+
934+
/**
935+
* @ticket 64314
936+
* @covers ::wp_save_post_revision
937+
*/
938+
public function test_wp_save_post_revision_with_array_post_meta() {
939+
// This filter is true by default, but this is explicitly to test looking for differences among non-scalar fields.
940+
add_filter( 'wp_save_post_revision_check_for_changes', '__return_true' );
941+
942+
$post_id = self::factory()->post->create();
943+
$meta_key = 'favorite_things';
944+
945+
// Ensure the post meta is saved with each revision.
946+
add_filter(
947+
'wp_post_revision_meta_keys',
948+
static function ( $meta_keys ) use ( $meta_key ) {
949+
$meta_keys[] = $meta_key;
950+
return $meta_keys;
951+
}
952+
);
953+
954+
// Ensure the post meta are used when determining whether a revision should be saved.
955+
add_filter(
956+
'_wp_post_revision_fields',
957+
static function ( $fields ) use ( $meta_key ) {
958+
$fields[ $meta_key ] = 'Favorite Things';
959+
return $fields;
960+
}
961+
);
962+
963+
// Set initial value.
964+
$initial_favorites = array(
965+
'raindrops on roses',
966+
'whiskers on kittens',
967+
'bright copper kettles',
968+
);
969+
update_post_meta( $post_id, $meta_key, $initial_favorites );
970+
971+
// Save the first revision.
972+
$revision_id_1 = wp_save_post_revision( $post_id );
973+
$this->assertIsInt( $revision_id_1, 'Expected first revision to be created.' );
974+
$this->assertCount( 1, wp_get_post_revisions( $post_id ), 'First revision should be created.' );
975+
$this->assertSame( $initial_favorites, get_post_meta( $revision_id_1, $meta_key, true ), 'Expected first revision post meta to have the initial value.' );
976+
977+
// Save the second revision.
978+
$updated_favorites = array_merge(
979+
$initial_favorites,
980+
array(
981+
'warm woolen mittens',
982+
'crisp apple strudels',
983+
'brown paper packages tied up with strings',
984+
)
985+
);
986+
update_post_meta( $post_id, $meta_key, $updated_favorites );
987+
$revision_id_2 = wp_save_post_revision( $post_id );
988+
$this->assertIsInt( $revision_id_2, 'Expected second revision to be created.' );
989+
$this->assertCount( 2, wp_get_post_revisions( $post_id ), 'Second revision should be created after array field change.' );
990+
$this->assertSame( $updated_favorites, get_post_meta( $revision_id_2, $meta_key, true ), 'Expected second revision post meta to have the updated value.' );
991+
}
933992
}

0 commit comments

Comments
 (0)