Make WordPress Core

Opened 7 years ago

Last modified 6 years ago

#43877 new defect (bug)

Do not run unnecessary `user_has_cap` filter if the caps to check for include `do_not_allow` already

Reported by: flixos90's profile flixos90 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Role/Capability Keywords: needs-unit-tests has-patch
Focuses: Cc:

Description

do_not_allow is a fake capability used essentially as a blacklist, saying that nobody can perform that action. It's typically returned in the map_meta_cap() result for an actual capability check. If do_not_allow is part of that array, it is immediately clear that the final result of the WP_User::has_cap() method will be false.

Currently however, the following code in the function still executes, including a user_has_cap filter. Since we already know the return value if do_not_allow is present in the $caps array checked for, everything happening afterwards is entirely unnecessary overhead. Especially since [40993] it should be clear that nothing can get around a do_not_allow being present.

For efficiency and possibly performance reasons, I suggest we check for do_not_allow right after the map_meta_cap() call, and if it is present, return false.

Attachments (1)

43877.diff (1.0 KB) - added by flixos90 7 years ago.

Download all attachments as: .zip

Change History (5)

@flixos90
7 years ago

#1 @flixos90
7 years ago

  • Keywords has-patch added; needs-patch removed

43877.diff fixes this problem. A unit test to verify that the following code does not run should be added as well (we could check to ensure the user_has_cap filter is not executed).

#2 @flixos90
6 years ago

@johnbillion Can you have a quick review, just to check whether my trail of thought is correct here?

#3 @dlh
6 years ago

It's a minor point, but I'm curious whether the unset( $capabilities['do_not_allow'] ); could be kept even with the early return introduced in the patch. While the function it served in [40993] would no longer apply, the idea it represents is still accurate, it seems to me.

#4 @johnbillion
6 years ago

I agree that this makes sense, however I have an interesting caveat. My Query Monitor plugin uses the user_has_cap filter for debugging capability checks. With this short-circuiting in place I'll have to modify the plugin to handle that specific situation via the map_meta_cap filter. This isn't a problem, but it might affect other plugins in a similar way if they're expecting the user_has_cap filter to fire for all capability checks on non-Multisite installations.

Note: See TracTickets for help on using tickets.