#52252 closed defect (bug) (fixed)
PHP Notice when `monthnum` query var is set without the `year` QV
Reported by: | dd32 | Owned by: | peterwilsoncc |
---|---|---|---|
Milestone: | 6.1 | Priority: | normal |
Severity: | normal | Version: | 4.3 |
Component: | Rewrite Rules | Keywords: | has-patch early needs-unit-tests commit |
Focuses: | Cc: |
Description (last modified by )
E_NOTICE: Undefined index: year in wp-includes/rewrite.php:413
/ E_NOTICE: Undefined index: monthnum in wp-includes/rewrite.php:413
It looks like [32648] assumes the permalink structures will always include both year
& monthnum
or monthnum
& day
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/rewrite.php?marks=400-403#L393
But a request such as ?monthnum=1
will cause it to check for the year
query var which might be unset.
(Props to the pentester hitting WordPress.org with many junk requests for bringing this to light)
Attachments (1)
Change History (31)
This ticket was mentioned in Slack in #core by hellofromtonya. View the logs.
4 years ago
#6
@
4 years ago
- Keywords reporter-feedback added; good-first-bug removed
- Milestone changed from 5.7 to Future Release
I'm so far unable to reproduce this problem. Requesting ?monthnum=2
on my local installation doesn't trigger a notice. There's a guard condition at the beginning of wp_resolve_numeric_slug_conflicts()
that protects against accessing the year
, monthnum
, or day
indexes of $query_vars
.
@dd32 Is anything else needed to trigger this notice? Is w.org running trunk?
#7
@
4 years ago
- Description modified (diff)
- Keywords reporter-feedback removed
Thanks for looking into it @johnbillion!
This notice was caused by a fuzzer hitting WordPress.org, 500+ query vars in a POST request against a news post, makes it hard to narrow down the cause, so sorry for the bad report.
There's a guard condition at the beginning of wp_resolve_numeric_slug_conflicts() that protects against accessing the year, monthnum, or day indexes of $query_vars.
The guard condition protects against the case of all 3 being not set, but not against situations where only one out of the expected vars is set.
Looking at the code, I can clearly see that on line 400 monthnum
being set without year
results in year
being looked for as an index on line 413, It seems that this happens early enough that the normal plugins such as Query monitor & Debug Bar don't pick it up the notice.
Is anything else needed to trigger this notice? Is w.org running trunk?
It looks like to trigger it with year
you need to have the permalink structure set to /%postname%/
and request https://example.com/?monthnum=1
It looks like to trigger it with monthnum
you need to have the permalink structure set to /%year%/%postname%/
and request https://example.com/?day=1
I can't see that day
is possible as a notice here, only year
/monthnum
. I'm guessing I either copy-paste wrong or caused the day
case in testing.
I pared it back as much as possible, and here's some debugging output for the year
case:
-
wp-includes/rewrite.php
412 412 // This is the potentially clashing slug. 413 413 $value = $query_vars[ $compare ]; 414 414 415 var_dump( compact( 'query_vars', 'permastructs', 'postname_index', 'compare', 'value' ) ); die(); 415 416 $post = get_page_by_path( $value, OBJECT, 'post' ); 416 417 if ( ! ( $post instanceof WP_Post ) ) { 417 418 return $query_vars;
results in:
GET https://wordpress.org/?monthnum=1 ( ! ) Notice: Undefined index: year in wp-includes/rewrite.php on line 413 Call Stack # Time Memory Function Location 1 0.0002 369824 {main}( ) .../index.php:0 2 0.0002 372720 require( 'wp-blog-header.php ) .../index.php:26 3 0.2574 6280864 wp( $query_vars = ??? ) .../wp-blog-header.php:16 4 0.2574 6280896 WP->main( $query_args = '' ) .../functions.php:1291 5 0.2574 6280896 WP->parse_request( $extra_query_vars = '' ) .../class-wp.php:750 6 0.2579 6304120 wp_resolve_numeric_slug_conflicts( $query_vars = ['monthnum' => '1'] ) .../class-wp.php:360 wp-includes/rewrite.php:415: array (size=5) 'query_vars' => array (size=1) 'monthnum' => string '1' (length=1) 'permastructs' => array (size=1) 0 => string '%postname%' (length=10) 'postname_index' => int 0 'compare' => string 'year' (length=4) 'value' => null
#9
@
4 years ago
- Milestone changed from Future Release to 5.7
Confirmed. Moving back to 5.7. That condition does indeed only guard against none of the three indexes being present.
This ticket was mentioned in PR #1027 on WordPress/wordpress-develop by peterwilsoncc.
4 years ago
#11
- Keywords has-unit-tests added; needs-unit-tests removed
#12
follow-up:
↓ 13
@
4 years ago
With RC this week, I'm inclined to move this to 5.8 early to avoid making Query related changes 2 days out.
I've started on some tests in the linked pull request but at this point don't have any assertions figured out. It's showing the notices.
#13
in reply to:
↑ 12
@
4 years ago
- Keywords early added
- Milestone changed from 5.7 to 5.8
Replying to peterwilsoncc:
I'm inclined to move this to 5.8 early to avoid making Query related changes 2 days out.
I agree, this isn't urgent and has existed for long enough not to rush any kind of fix.
This ticket was mentioned in Slack in #core by lukecarbis. View the logs.
3 years ago
This ticket was mentioned in Slack in #core by chaion07. View the logs.
3 years ago
#16
@
3 years ago
- Keywords needs-unit-tests added; has-unit-tests removed
Adjusting the keywords here to more accurately represent the state of tests. The PR touches a PHPUnit file, which triggers the has-unit-tests
keyword, but the needed assertions are not yet added.
This ticket was mentioned in Slack in #core by chaion07. View the logs.
3 years ago
This ticket was mentioned in Slack in #core by chaion07. View the logs.
3 years ago
#20
@
3 years ago
- Milestone changed from 5.8 to 5.9
Unfortunately this one has run out of time as 5.8 beta 1 is being packaged in less than an hour. Punting to 5.9.
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
3 years ago
This ticket was mentioned in Slack in #core-test by hellofromtonya. View the logs.
3 years ago
#23
@
3 years ago
- Milestone changed from 5.9 to Future Release
Query changes by design need careful consideration and plenty of soak time to ensure nothing breaks. With 5.9 feature freeze ~2 days away, it's too late in the release cycle for a change to query. Punting this out of 5.9. As the next milestone is not yet available, moving to Future Release
. Once available, feel free to move into the next release.
#25
@
2 years ago
- Keywords commit added
- Milestone changed from Future Release to 6.1
- Owner set to peterwilsoncc
- Status changed from reviewing to accepted
I've updated the tests in the linked pull request and merged in @dd32's patch.
The tests are weird because they assert true
is true
(which is true), however they're dummy tests as the real test is to assert that there are no notices thrown.
In Tests_Privacy_wpPrivacyDeleteOldExportFiles::test_non_existent_folders_should_not_cause_errors()
there is a similar test that does the same thing. Thus I decided to follow precedent rather than add an annotation marking the test not risky.
I think this is good for commit.
#26
@
2 years ago
- Component changed from Query to Rewrite Rules
Moving this to the Rewrite Rules component as that is where the notice is thrown and the fix applied.
peterwilsoncc commented on PR #1027:
2 years ago
#28
Merged https://core.trac.wordpress.org/changeset/53857 / 3e866f8b8f
adding array_key_exists check