Skip to content

Commit 244b9c1

Browse files
authored
Merge branch 'trunk' into add/basic-relay-support
2 parents 9fcd201 + b3a09d0 commit 244b9c1

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
* Support for sending Activities to ActivityPub Relays, to improve discoverability of public content.
13+
* Upgrade script to fix Follower json representations with unescaped backslashes.
1314

1415
### Changed
1516

includes/class-migration.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ public static function maybe_migrate() {
186186
add_action( 'init', 'flush_rewrite_rules', 20 );
187187
}
188188
if ( \version_compare( $version_from_db, 'unreleased', '<' ) ) {
189+
\wp_schedule_single_event( \time(), 'activitypub_upgrade', array( 'update_actor_json_slashing' ) );
189190
\wp_schedule_single_event( \time(), 'activitypub_upgrade', array( 'update_comment_author_emails' ) );
190191
}
191192

@@ -635,6 +636,50 @@ public static function create_comment_outbox_items( $batch_size = 50, $offset =
635636
return null;
636637
}
637638

639+
/**
640+
* Update _activitypub_actor_json meta values to ensure they are properly slashed.
641+
*
642+
* @param int $batch_size Optional. Number of meta values to process per batch. Default 100.
643+
* @param int $offset Optional. Number of meta values to skip. Default 0.
644+
* @return array|null Array with batch size and offset if there are more meta values to process, null otherwise.
645+
*/
646+
public static function update_actor_json_slashing( $batch_size = 100, $offset = 0 ) {
647+
global $wpdb;
648+
649+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
650+
$meta_values = $wpdb->get_results(
651+
$wpdb->prepare(
652+
"SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_activitypub_actor_json' LIMIT %d OFFSET %d",
653+
$batch_size,
654+
$offset
655+
)
656+
);
657+
658+
foreach ( $meta_values as $meta ) {
659+
$json = \json_decode( $meta->meta_value, true );
660+
661+
// If json_decode fails, try adding slashes.
662+
if ( null === $json && \json_last_error() !== JSON_ERROR_NONE ) {
663+
$escaped_value = \preg_replace( '#\\\\(?!["\\\\/bfnrtu])#', '\\\\\\\\', $meta->meta_value );
664+
$json = \json_decode( $escaped_value, true );
665+
666+
// Update the meta if json_decode succeeds with slashes.
667+
if ( null !== $json && \json_last_error() === JSON_ERROR_NONE ) {
668+
\update_post_meta( $meta->post_id, '_activitypub_actor_json', \wp_slash( $escaped_value ) );
669+
}
670+
}
671+
}
672+
673+
if ( \count( $meta_values ) === $batch_size ) {
674+
return array(
675+
'batch_size' => $batch_size,
676+
'offset' => $offset + $batch_size,
677+
);
678+
}
679+
680+
return null;
681+
}
682+
638683
/**
639684
* Update comment author emails with webfinger addresses for ActivityPub comments.
640685
*

readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ For reasons of data protection, it is not possible to see the followers of other
132132
= Unreleased =
133133

134134
* Added: Support for sending Activities to ActivityPub Relays, to improve discoverability of public content.
135+
* Added: Upgrade script to fix Follower json representations with unescaped backslashes.
135136
* Changed: Bumped minimum required WordPress version to 6.4.
136137
* Changed: Use a later hook for Posts to get published to the Outbox, to get sure all `post_meta`s and `taxonomy`s are set stored properly.
137138
* Changed: Use webfinger as author email for comments from the Fediverse.

tests/includes/class-test-migration.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
namespace Activitypub\Tests;
99

10+
use Activitypub\Collection\Followers;
1011
use Activitypub\Collection\Outbox;
1112
use Activitypub\Migration;
1213
use Activitypub\Comment;
14+
use Activitypub\Model\Follower;
1315

1416
/**
1517
* Test class for Activitypub Migrate.
@@ -598,6 +600,45 @@ public function test_create_comment_outbox_items_batching() {
598600
$this->assertNull( $result );
599601
}
600602

603+
/**
604+
* Test update_actor_json_slashing updates unslashed meta values.
605+
*
606+
* @covers ::update_actor_json_slashing
607+
*/
608+
public function test_update_actor_json_slashing() {
609+
$follower = new Follower();
610+
$follower->from_array(
611+
array(
612+
'type' => 'Person',
613+
'summary' => '<p>unescaped backslash 04\2024</p>',
614+
)
615+
);
616+
$unslashed_json = $follower->to_json();
617+
618+
$post_id = self::factory()->post->create(
619+
array(
620+
'post_type' => Followers::POST_TYPE,
621+
'meta_input' => array( '_activitypub_actor_json' => $unslashed_json ),
622+
)
623+
);
624+
625+
$original_meta = \get_post_meta( $post_id, '_activitypub_actor_json', true );
626+
$this->assertNull( \json_decode( $original_meta, true ) );
627+
$this->assertEquals( JSON_ERROR_SYNTAX, \json_last_error() );
628+
629+
$result = Migration::update_actor_json_slashing();
630+
631+
// No additional batch should be scheduled.
632+
$this->assertNull( $result );
633+
634+
$updated_meta = \get_post_meta( $post_id, '_activitypub_actor_json', true );
635+
636+
// Verify the updated value can be successfully decoded.
637+
$decoded = \json_decode( $updated_meta, true );
638+
$this->assertNotNull( $decoded, 'Updated meta should be valid JSON' );
639+
$this->assertEquals( JSON_ERROR_NONE, \json_last_error() );
640+
}
641+
601642
/**
602643
* Test update_comment_author_emails updates emails with webfinger addresses.
603644
*

0 commit comments

Comments
 (0)