Make WordPress Core

Opened 15 months ago

Last modified 13 months ago

#59235 new defect (bug)

AJAX request returns critical error in class-wp-date-query.php

Reported by: reklwera's profile reklwera Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.1
Component: Query Keywords: reporter-feedback
Focuses: Cc:

Description

This is due to the mktime gets the $year variable as string and not int.

This is the error code given:

PHP Fatal error:  Uncaught TypeError: mktime(): Argument #6 ($year) must be of type ?int, string given in /wp-includes/class-wp-date-query.php:320

The code is:

<?php
                // Days per year.
                if ( array_key_exists( 'year', $date_query ) ) {
                        /*
                         * If a year exists in the date query, we can use it to get the days.
                         * If multiple years are provided (as in a BETWEEN), use the first one.
                         */
                        if ( is_array( $date_query['year'] ) ) {
                                $_year = reset( $date_query['year'] );
                        } else {
                                $_year = $date_query['year'];
                        }

                        $max_days_of_year = gmdate( 'z', mktime( 0, 0, 0, 12, 31, $_year ) ) + 1;
                } else {
                        // Otherwise we use the max of 366 (leap-year).
                        $max_days_of_year = 366;
                }

To fix this one can be sure to use intval:

<?php
                // Days per year.
                if ( array_key_exists( 'year', $date_query ) ) {
                        /*
                         * If a year exists in the date query, we can use it to get the days.
                         * If multiple years are provided (as in a BETWEEN), use the first one.
                         */
                        if ( is_array( $date_query['year'] ) ) {
                                $_year = intval(reset( $date_query['year'] ));
                        } else {
                                $_year = intval($date_query['year']);
                        }

                        $max_days_of_year = gmdate( 'z', mktime( 0, 0, 0, 12, 31, $_year ) ) + 1;
                } else {
                        // Otherwise we use the max of 366 (leap-year).
                        $max_days_of_year = 366;
                }

Change History (3)

This ticket was mentioned in PR #5108 on WordPress/wordpress-develop by wera-as.


15 months ago
#1

Fixes this error: PHP Fatal error: Uncaught TypeError: mktime(): Argument #6 ($year) must be of type ?int, string given in /wp-includes/class-wp-date-query.php:320

Trac ticket: [](https://core.trac.wordpress.org/ticket/59235)

#2 @jrf
15 months ago

@reklwera Thanks for reporting this and welcome to Trac.

Primarily this is a case of incorrect input being passed to the date query, so this needs a backtrace and should be solved at the point where the incorrect data is being passed.

The year key for the DateQuery class is explicitly documented as only accepting int or and array of int values, while the error indicates that a string or and array of strings was passed.

So, based on this, the patch provided on GitHub is invalid as this is not the right way to solve this. We could consider it, but in that case, I would want calls to _doing_it_wrong() to be added as well as the data should be called out as invalid to give the dev the chance to fix it.

#3 @hellofromTonya
13 months ago

  • Focuses php-compatibility removed
  • Keywords reporter-feedback added; has-patch removed
  • Version changed from trunk to 4.1

Hello @reklwera,

Welcome to WordPress Core's Trac :)

As @jrf noted in comment:2, a full backtrace is needed to find the root cause:

Primarily this is a case of incorrect input being passed to the date query, so this needs a backtrace and should be solved at the point where the incorrect data is being passed.

There are good suggestions in the PR for better defensive guarding, such as dealing with false returned from reset().

I agree with @jrf that _doing_it_wrong() or wp_trigger_error() are appropriate to avoid silently bailing out or handling incorrect given inputs.

Any code changes will also need unit tests.

Ticket updates:

  • Version: The code was introduced during 4.1 via [31396] / #31001.
  • Keywords: Removing has-patch as the PR is now closed and its branch deleted.
  • Focus: php-compatibility keyword is reserved for denoting incompatibilities with a specific PHP version. When there's an incompatibility, it pairs with the phpNN keyword. See the handbook.
Note: See TracTickets for help on using tickets.