WordPress.org

Make WordPress Core

Opened 6 years ago

Closed 6 years ago

#32073 closed enhancement (wontfix)

Undefined offset: 0 warning in wp-includes\capabilities.php on line 1119

Reported by: hubertnguyen Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.1.1
Component: General Keywords: has-patch
Focuses: Cc:

Description

Hello,

I'm sometime getting a PHP Notice:

Notice: Undefined offset: 0 in \wp-includes\capabilities.php on line 1119

It happens when $args is empty.

$post = get_post( $args[0] );

I've seen someone else complain of the same thing in the support forum:

https://wordpress.org/support/topic/php-error-on-addingupdating-woocommerce-product

There is no real functional issues, but when developing with WP_DEBUG = 1, this creates warnings that are a bit annoying. since get_post() supports a null argument, would it be OK to do something like this:

if (empty($args)) {$post = get_post( null );}
else { $post = get_post( $args[0] ); }

Thank you,

Attachments (3)

32073-1.patch (1.4 KB) - added by dmchale 6 years ago.
32073-2.patch (1.8 KB) - added by dmchale 6 years ago.
32073.3.diff (2.2 KB) - added by MikeHansenMe 6 years ago.

Download all attachments as: .zip

Change History (8)

#1 @dmchale
6 years ago

IMO a more proper fix would be to bail from each "case" which requires $args[0] to be set when it's not. I'm not sure quite what WordPress is doing when these Notices are being thrown, but I have to imagine this is probably cleaner? Fewer lines of code per instance, and prevents unnecessary calls to get_post().

Attaching a patch that adds the following code into the delete_page, edit_page, read_page, publish_post, and add_post_meta portions of the switch statement.

if ( ! isset( $args[0] ) )
    break;

@dmchale
6 years ago

#2 @hubertnguyen
6 years ago

Right now, at \wp-includes\capabilities.php on line 1119, when args is empty, the current Post is being returned by getpost() and the rest would execute, so "break" would take a substantially different path.

@dmchale
6 years ago

#3 @dmchale
6 years ago

Sorry, you're completely correct. New patch uploaded with ternary logic, I think this is what you were suggesting originally

$post = ( isset( $args[0] ) ) ? get_post( $args[0] ) : get_post();

@MikeHansenMe
6 years ago

#4 @MikeHansenMe
6 years ago

  • Keywords has-patch added

Updated patch to correct space/tab issue and from src dir.

#5 @boonebgorges
6 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Is there any use of current_user_can() in WP core that causes these notices to be thrown? A glance through the codebase suggests that WP is always passing a post ID for these cap checks, which means that $args[0] will always be set.

I think we should close as wontfix. If no post ID is explicitly passed to current_user_can(), it happens to be the case that we fall back on get_post( null ). However, this is bad practice. Singular, mapped cap checks should always be performed against specific posts. Using current_user_can( 'delete_post' ) as shorthand for current_user_can( 'delete_post', $GLOBALS['post']->ID ) is bound to cause developers to introduce permissions-related bugs, because the contents of the $post global can vary oddly in secondary queries, nested queries, and outside the post loop. The PHP notice that is being reported in this case should act as a warning to plugin devs to be more specific.

If anyone can point to a place in WP where we're not passing a post_id to one of these cap checks, please feel free to reopen with details.

Note: See TracTickets for help on using tickets.