#35902 closed defect (bug) (fixed)
WP_Query::is_page() can return incorrect results when post title includes a slash
Reported by: | mikejolley | Owned by: | boonebgorges |
---|---|---|---|
Milestone: | 4.5 | Priority: | normal |
Severity: | normal | Version: | |
Component: | General | Keywords: | has-patch has-unit-tests |
Focuses: | Cc: |
Description
In WP_Query::is_page(), the following evaluations are made to determine if the queried object matches the supplied page property:
if ( in_array( (string) $page_obj->ID, $page ) ) { return true; } elseif ( in_array( $page_obj->post_title, $page ) ) { return true; } elseif ( in_array( $page_obj->post_name, $page ) ) { return true; } else {
If you have a page with a slash in the name, for example, 4/6 Sample Page, WP_Query::is_page(4) returns true, even if the actual page ID is something else.
I traced this back to the line:
} elseif ( in_array( $page_obj->post_title, $page ) ) {
In my test case, $page is:
array(1) { [0]=> int(4) }
If you cast 4/6 Sample Page to int, it becomes int(4) causing the match. This comparison should be strict...
There was some discussion around this in ticket https://core.trac.wordpress.org/ticket/24674, however, I don't see a fix for the case I posted above. Only IDs were fixed.
When comparing string based post_titles, ideally the $page should be cast to string to prevent the above case returning true.
To fix this I believe we can do some more intelligent casting.
The first rule:
if ( in_array( (string) $page_obj->ID, $page ) ) {
ID is cast to string and compared against $page with type array, contents unknown.
The second rule we already know title is string:
} elseif ( in_array( $page_obj->post_title, $page ) ) {
Same for the postname rule:
} elseif ( in_array( $page_obj->post_name, $page ) ) {
Since all comparisons use string, we should be able to safely cast the array values to a string too:
$page = array_map( 'strval', (array) $page );
This fixes all comparisons and prevents the bug occurring.
I found this bug when investigating https://github.com/woothemes/woocommerce/issues/10404. Page name was 4/6 Sample Page, and in my case my shop page was ID 4. Because of this, checks for page ID 4 (shop) returned true on 4/6 Sample Page incorrectly.
Patch to follow...
Attachments (2)
Change History (9)
#4
@
9 years ago
- Keywords has-unit-tests added; needs-unit-tests removed
- Milestone changed from Awaiting Review to 4.5
Fix for 35902