Skip to content

REST API: Avoid infinite recursion when a post is its own parent - #13924

Open
jorgefilipecosta wants to merge 1 commit into
WordPress:trunkfrom
jorgefilipecosta:fix/rest-read-permission-self-parent
Open

jorgefilipecosta wants to merge 1 commit into
WordPress:trunkfrom
jorgefilipecosta:fix/rest-read-permission-self-parent

Conversation

@jorgefilipecosta

Copy link
Copy Markdown
Member

WP_REST_Posts_Controller::check_read_permission() checks the parent of an inherit post. When a post is its own parent, the check calls itself until PHP runs out of memory. It reaches that branch for anyone who can't read the post directly, including logged-out visitors, so one self-parented attachment makes GET /wp/v2/media/<id>, and every GET /wp/v2/media page that lists it, end in a fatal error.

wp_insert_post() refuses to make a post its own parent, but imports and direct database writes can leave one, and get_post_status() and get_post_ancestors() already handle it. This skips the parent check for a self-parented post, so it falls through to the existing branch for posts without a parent and is treated as published, as get_post_status() does. Longer parent loops aren't covered, the same as in get_post_status().

Testing Instructions

  1. Make an attachment its own parent: wp db query "UPDATE wp_posts SET post_parent = ID WHERE ID = <id>", then wp cache flush.
  2. Logged out, open /wp-json/wp/v2/media/<id> and /wp-json/wp/v2/media.
  3. On trunk both end in a memory exhaustion fatal error. With this change both return the attachment.

The new test_get_item_inherit_status_with_self_parent gets the PHPUnit process killed on trunk and passes here.

Trac ticket:

Use of AI Tools


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

`WP_REST_Posts_Controller::check_read_permission()` checks the parent of an `inherit` post. When the post was its own parent, the check called itself until PHP ran out of memory, for anyone who cannot read the post directly, including logged-out visitors.

A self-parented post is now treated like one without a parent, as `get_post_status()` does.
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@jorgefilipecosta
jorgefilipecosta marked this pull request as ready for review October 23, 2026 22:22
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props jorgefilipecosta.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant