Skip to content
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

Block “Fediverse Followers” crashes page/blog #571

Closed
cybeardjm opened this issue Nov 23, 2023 · 24 comments · Fixed by #586
Closed

Block “Fediverse Followers” crashes page/blog #571

cybeardjm opened this issue Nov 23, 2023 · 24 comments · Fixed by #586
Assignees
Labels
Needs triage [Type] Bug Something isn't working

Comments

@cybeardjm
Copy link

cybeardjm commented Nov 23, 2023

Quick summary

Had a published page to publicize the fedified status of both of my blogs, created some time ago.
Since then, the plugin was updated to latest version 1.1.0, then 1.2.0.

When visiting the page, it’s now broken or not available due to a critical error on the blog.
When trying to create a new post/page with the block, "This block has encountered an error and cannot be previewed." and draft can’t be saved.
When trying to edit a post/page containing the block, critical error...

Steps to reproduce

1 - Create a new post.
2 - Add "Fediverse Followers" block.

What you expected to happen

Block doesn't crash page/blog when viewed, allows editing, etc.

What actually happened

The PHP error log shows multiple (many!) errors like this one (real domain name replaced by (domain) _below):

[13-Nov-2023 23:02:18 UTC] PHP Fatal error: Uncaught TypeError: ltrim(): Argument #1 ($string) must be of type string, array given in /srv/data/web/vhosts/(domain)/htdocs/wp-includes/formatting.php:4494
Stack trace:
#0 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/formatting.php(4494): ltrim()
#1 /srv/data/web/vhosts/(domain)/htdocs/wp-content/plugins/activitypub/includes/class-blocks.php(143): esc_url()
#2 /srv/data/web/vhosts/(domain)/htdocs/wp-content/plugins/activitypub/includes/class-blocks.php(119): Activitypub\Blocks::render_follower()
#3 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp-block.php(258): Activitypub\Blocks::render_follower_block()
#4 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/blocks.php(1484): WP_Block->render()
#5 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/blocks.php(1522): render_block()
#6 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp-hook.php(324): do_blocks()
#7 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/plugin.php(205): WP_Hook->apply_filters()
#8 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php(620): apply_filters()
#9 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php(451): WP_REST_Revisions_Controller->prepare_item_for_response()
#10 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php(253): WP_REST_Autosaves_Controller->prepare_item_for_response()
#11 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/class-wp-rest-server.php(1193): WP_REST_Autosaves_Controller->create_item()
#12 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/class-wp-rest-server.php(1041): WP_REST_Server->respond_to_request()
#13 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api/class-wp-rest-server.php(431): WP_REST_Server->dispatch()
#14 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/rest-api.php(424): WP_REST_Server->serve_request()
#15 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp-hook.php(324): rest_api_loaded()
#16 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#17 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/plugin.php(565): WP_Hook->do_action()
#18 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp.php(418): do_action_ref_array()
#19 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/class-wp.php(813): WP->parse_request()
#20 /srv/data/web/vhosts/(domain)/htdocs/wp-includes/functions.php(1336): WP->main()
#21 /srv/data/web/vhosts/(domain)/htdocs/wp-blog-header.php(16): wp()
#22 /srv/data/web/vhosts/(domain)/htdocs/index.php(17): require('...')
#23 {main} thrown in /srv/data/web/vhosts/(domain)/htdocs/wp-includes/formatting.php on line 4494

Impact

One

Available workarounds?

No and the platform is unusable

Logs or notes

No response

@cybeardjm cybeardjm added [Type] Bug Something isn't working Needs triage labels Nov 23, 2023
@pfefferle
Copy link
Member

Do you see the same issue when paging through the followers list in wp-admin?

@pfefferle
Copy link
Member

pfefferle commented Nov 28, 2023

Respectively is it possible for you to check (and maybe provide me) the url field for that follower or can you maybe provide me the profile-URL (privately) that I can debug it?

@cybeardjm
Copy link
Author

cybeardjm commented Nov 28, 2023 via email

@pfefferle
Copy link
Member

Do you use DB cleanup plugins?

@cybeardjm
Copy link
Author

cybeardjm commented Nov 28, 2023 via email

@pfefferle
Copy link
Member

@cybeardjm this is paged, so it shows only the last 10 posts, but it has 78 pages.

What cleanup plugin do you use?

@cybeardjm
Copy link
Author

cybeardjm commented Nov 28, 2023 via email

@cybeardjm
Copy link
Author

cybeardjm commented Nov 28, 2023 via email

@cybeardjm
Copy link
Author

cybeardjm commented Nov 28, 2023 via email

@snarfed
Copy link

snarfed commented Nov 29, 2023

Looks like @cybeardjm is right, the AP actor https://fed.brid.gy/djm.didiermary.fr does have a multiply valued url field. This is because https://djm.didiermary.fr/ has two u-urls, and Bridgy Fed propagates both of them into the AP actor. It looks like:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    "https://w3id.org/security/v1"
  ],
  "id": "https://fed.brid.gy/djm.didiermary.fr",
  "url": [
    "https://fed.brid.gy/r/https://djm.didiermary.fr/",
    "acct:[email protected]"
  ]
  "..."
}

I'll grant that this is less common, but it's definitely valid AS2. Note the examples in https://www.w3.org/TR/activitystreams-vocabulary/#dfn-url and that it's not marked Functional. From https://www.w3.org/TR/activitystreams-vocabulary/#properties :

Properties marked as being "Functional" can have only one value. Items not marked as "Functional" can have multiple values.

@pfefferle, do you need any help fixing this on the plugin's side so that it supports multiply valued urls?

@cybeardjm
Copy link
Author

cybeardjm commented Nov 29, 2023

Thx @snarfed - the alias (acct:) is a good solution to avoid having to exist as (longdomain) @ (longdomain).
I saw it, I used it... ;-) and it worked...

@pfefferle
Copy link
Member

@snarfed thanks, I know about it, but had hoped that it would simply always be used as string 🙄

I hoped to avoid checking for string, Link Object, array of strings and array of Link Objects 😔

@pfefferle
Copy link
Member

Just out of curiosity... is there a benefit of adding the acct URI @snarfed ?

@snarfed
Copy link

snarfed commented Nov 29, 2023

Fair question! I'm not doing it deliberately, I just pass through everything in u-url.

snarfed added a commit to snarfed/bridgy-fed that referenced this issue Nov 29, 2023
@snarfed
Copy link

snarfed commented Nov 29, 2023

@pfefferle @cybeardjm I've updated Bridgy Fed to omit these acct: URIs. url will still be an array for some actors, both BF and non-BF, eg https://fed.brid.gy/tantek.com, so @pfefferle you may still want to handle it, but in the common case, including https://fed.brid.gy/djm.didiermary.fr , it's now a single string.

@pfefferle
Copy link
Member

pfefferle commented Nov 30, 2023

@snarfed I will fix it and I understand your idea behind that, but I had another look at the spec and it describes the URL filed like followed:

Identifies one or more links to representations of the object 

So in this case the URL should link to different representations of Tanteks Actor Profile and not to his other social network profiles?!?

In my understanding, it shouldn't matter which profile from the list I use, it should always represent the Actor tantek.com, but in the case of fed.brid.gy, I can only use the first one for ActivityPub (get profile informations via content negotiation for example)!

I would recommend using the attachment (Link) in that case.

@snarfed
Copy link

snarfed commented Nov 30, 2023

Hmm! https://www.w3.org/TR/activitystreams-vocabulary/#dfn-url , right? I don't think "representations" necessarily means AS2 actors. The example URLs in that section point to .pdf and .html URLs, which presumably don't serve AS2.

@pfefferle
Copy link
Member

True, but still more a rel="alternate" instead of a rel="me"!?!

@snarfed
Copy link

snarfed commented Nov 30, 2023

Not sure I follow. Where are the rels here? On the source web site? What are you proposing I do with them?

@pfefferle
Copy link
Member

The "rel" thing was just meant as an example to emphasize my point (which probably didn't work out so well).

What I meant to say is that the spec says that the URL is used to have different representations of an object (similar to rel="alternate" for HTTP and HTML), but fed.brid.gy uses all kinds of other URLs that are also about or from the person (re-use the rel="me").

@snarfed
Copy link

snarfed commented Nov 30, 2023

True! I would argue those two ideas are more similar than different. Eg my Facebook profile https://www.facebook.com/snarfed.org is about or from me, and it also seems like another "representation of the object" of my AP actor https://fed.brid.gy/snarfed.org , even if that Facebook URL doesn't serve AS2.

Regardless, the issue here for @cybeardjm at least is fixed. I think I have seen some other fediverse servers serve array-valued urls though, so independent of Bridgy Fed, you may want to handle that sooner or later, if only to not crash. 😁

If you want some resolution on the spec interpretation here, feel free to file an issue on https://github.com/w3c/activitystreams/issues ! Evan has been triaging those issues regularly, he'd get to it soon.

pfefferle added a commit that referenced this issue Dec 5, 2023
* fix #571

* support empty values

* fix phpcs issues

* test for `null`

* use `object_to_uri`  on followers list
@snarfed
Copy link

snarfed commented Jul 3, 2024

Hi all! We're seeing this again on @StarrWulfe's site. Here's the full error and stack trace and activity below; I'll let @StarrWulfe post details on his site, WP and plugin versions, etc.

500 Server Error: Internal Server Error for url: https://starrwulfe.xyz/wp-json/activitypub/1.0/actors/1/inbox ;

{
  "code": "internal_server_error",
  "message": "...",
  "file": "/var/www/wordpress/wp-includes/formatting.php",
  "line": 4494
}},"additional_errors":[]}

<p>There has been a critical error on this website.</p><p><a href=\"https://wordpress.org/documentation/article/faq-troubleshooting/\">Learn more about troubleshooting WordPress.</a></p>","data":{"status":500,"error":{"type":1,"message":"Uncaught TypeError: ltrim(): Argument #1 ($string) must be of type string, array given in /var/www/wordpress/wp-includes/formatting.php:4494
Stack trace:
#0 /var/www/wordpress/wp-includes/formatting.php(4494): ltrim()
#1 /var/www/wordpress/wp-includes/formatting.php(4620): esc_url()
#2 /var/www/wordpress/wp-includes/formatting.php(4602): sanitize_url()
#3 /var/www/wordpress/wp-content/plugins/activitypub/includes/collection/class-interactions.php(60): esc_url_raw()
#4 /var/www/wordpress/wp-content/plugins/activitypub/includes/handler/class-create.php(61): Activitypub\\Collection\\Interactions::add_comment()
#5 /var/www/wordpress/wp-includes/class-wp-hook.php(324): Activitypub\\Handler\\Create::handle_create()
#6 /var/www/wordpress/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#7 /var/www/wordpress/wp-includes/plugin.php(517): WP_Hook->do_action()
#8 /var/www/wordpress/wp-content/plugins/activitypub/includes/rest/class-inbox.php(136): do_action()
#9 /var/www/wordpress/wp-includes/rest-api/class-wp-rest-server.php(1230): Activitypub\\Rest\\Inbox::user_inbox_post()
#10 /var/www/wordpress/wp-includes/rest-api/class-wp-rest-server.php(1063): WP_REST_Server->respond_to_request()
#11 /var/www/wordpress/wp-includes/rest-api/class-wp-rest-server.php(439): WP_REST_Server->dispatch()
#12 /var/www/wordpress/wp-includes/rest-api.php(428): WP_REST_Server->serve_request()
#13 /var/www/wordpress/wp-includes/class-wp-hook.php(324): rest_api_loaded()
#14 /var/www/wordpress/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#15 /var/www/wordpress/wp-includes/plugin.php(565): WP_Hook->do_action()
#16 /var/www/wordpress/wp-includes/class-wp.php(418): do_action_ref_array()
#17 /var/www/wordpress/wp-includes/class-wp.php(813): WP->parse_request()
#18 /var/www/wordpress/wp-includes/functions.php(1336): WP->main()
#19 /var/www/wordpress/wp-blog-header.php(16): wp()
#20 /var/www/wordpress/index.php(17): require('...')
#21 {main}
  thrown

Here's the activity that was delivered:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Create",
  "id": "https://bsky.brid.gy/convert/ap/at://did:plc:ke5adm7cnbxc5ek34fsrt5bt/app.bsky.feed.post/3kwdw6vbjsc2f#bridgy-fed-create",
  "actor": "https://bsky.brid.gy/ap/did:plc:ke5adm7cnbxc5ek34fsrt5bt",
  "published": "2024-07-03T03:00:53.419317+00:00",
  "to": ["https://www.w3.org/ns/activitystreams#Public"]
  "object": {
    "type": "Note",
    "id": "https://bsky.brid.gy/convert/ap/at://did:plc:ke5adm7cnbxc5ek34fsrt5bt/app.bsky.feed.post/3kwdw6vbjsc2f",
    "url": "https://fed.brid.gy/r/https://bsky.app/profile/did:plc:ke5adm7cnbxc5ek34fsrt5bt/post/3kwdw6vbjsc2f",
    "attributedTo": "https://bsky.brid.gy/ap/did:plc:ke5adm7cnbxc5ek34fsrt5bt",
    "inReplyTo": "https://starrwulfe.xyz/notes/2024/07/593c2fce1a/",
    "content": "<p>This is a reply from Bsky. If all goes well, it should be routed back into the <a href=\"https://bsky.brid.gy/hashtag/fediverse\">#fediverse</a> and also picked up by the Friends plugin and as a comment on the blog page that originated it (at the <a href=\"https://starrwulfe.xyz/b/3bVT\">starrwulfe.xyz/b/3bVT</a> link above)<br><br><a title=\"This is a test note from my blog ...\" href=\"https://starrwulfe.xyz/b/3bVT\">This is a test note from my bl...</a></p>",
    "contentMap": {
      "en": "<p>This is a reply from Bsky. If all goes well, it should be routed back into the <a href=\"https://bsky.brid.gy/hashtag/fediverse\">#fediverse</a> and also picked up by the Friends plugin and as a comment on the blog page that originated it (at the <a href=\"https://starrwulfe.xyz/b/3bVT\">starrwulfe.xyz/b/3bVT</a> link above)<br><br><a title=\"This is a test note from my blog ...\" href=\"https://starrwulfe.xyz/b/3bVT\">This is a test note from my bl...</a></p>"
    }
    "content_is_html": true,
    "published": "2024-07-03T03:00:50.936Z",
    "tag": [
      {
        "type": "Hashtag",
        "name": "#fediverse",
        "href": "https://bsky.brid.gy/hashtag/fediverse"
      },
      {
        "url": "https://starrwulfe.xyz/b/3bVT",
        "type": "Article",
        "name": "starrwulfe.xyz/b/3bVT"
      },
      {
        "type": "Mention",
        "href": "https://starrwulfe.xyz/author/starrwulfe/"
      }
    ],
    "to": ["https://www.w3.org/ns/activitystreams#Public"],
    "cc": [
      "https://starrwulfe.xyz/author/starrwulfe/",
      "https://starrwulfe.xyz/wp-json/activitypub/1.0/actors/1/followers",
      "https://www.w3.org/ns/activitystreams#Public"
    ],
  },
}

@snarfed
Copy link

snarfed commented Jul 3, 2024

Ah, looks like root cause may be the same, https://bsky.brid.gy/ap/did:plc:ke5adm7cnbxc5ek34fsrt5bt has an array-valued url field:

  "url": [
    "https://bsky.brid.gy/r/https://bsky.app/profile/starrwulfe.xyz",
    "https://starrwulfe.xyz/"
  ]

@StarrWulfe
Copy link

I'm on ActivityPub Plugin 2.5.0, Friends 2.9.3, running Wordpress 6.5.5.

pfefferle added a commit that referenced this issue Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs triage [Type] Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants