diff --git a/src/wp-includes/cron.php b/src/wp-includes/cron.php index 7bbb0036f1c02..97336c3aaf566 100644 --- a/src/wp-includes/cron.php +++ b/src/wp-includes/cron.php @@ -316,6 +316,17 @@ function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array(), $wp return false; } + if ( ! is_numeric( $event->interval ) || $event->interval <= 0 ) { + if ( $wp_error ) { + return new WP_Error( + 'invalid_interval', + __( 'Event schedule has invalid interval.' ) + ); + } + + return false; + } + $key = md5( serialize( $event->args ) ); $crons = _get_cron_array(); @@ -444,12 +455,19 @@ function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array(), $ } // Now we assume something is wrong and fail to schedule. - if ( 0 === $interval ) { + if ( ! is_numeric( $interval ) || $interval <= 0 ) { if ( $wp_error ) { - return new WP_Error( - 'invalid_schedule', - __( 'Event schedule does not exist.' ) - ); + if ( ! isset( $schedules[ $recurrence ] ) ) { + return new WP_Error( + 'invalid_schedule', + __( 'Event schedule does not exist.' ) + ); + } else { + return new WP_Error( + 'invalid_interval', + __( 'Event schedule has invalid interval.' ) + ); + } } return false; diff --git a/tests/phpunit/tests/cron.php b/tests/phpunit/tests/cron.php index 7abaf5c92095e..b4536c499fa82 100644 --- a/tests/phpunit/tests/cron.php +++ b/tests/phpunit/tests/cron.php @@ -847,6 +847,7 @@ public function test_invalid_timestamp_for_event_returns_error() { /** * @ticket 49961 + * @ticket 64404 * * @covers ::wp_schedule_event * @covers ::wp_reschedule_event @@ -862,6 +863,99 @@ public function test_invalid_recurrence_for_event_returns_error() { $this->assertSame( 'invalid_schedule', $rescheduled_event->get_error_code() ); } + /** + * @ticket 64404 + * + * @covers ::wp_schedule_event + * @covers ::wp_reschedule_event + */ + public function test_invalid_schedule_interval_returns_error() { + add_filter( + 'cron_schedules', + static function ( $schedules ) { + $schedules['backwards_in_time'] = array( + 'interval' => -3600, + 'display' => 'Back to the future!', + ); + return $schedules; + } + ); + + $event = wp_schedule_event( time(), 'backwards_in_time', 'hook', array(), true ); + $this->assertWPError( $event ); + $this->assertSame( 'invalid_interval', $event->get_error_code() ); + + $rescheduled_event = wp_reschedule_event( time(), 'backwards_in_time', 'hook', array(), true ); + $this->assertWPError( $rescheduled_event ); + $this->assertSame( 'invalid_interval', $rescheduled_event->get_error_code() ); + } + + /** + * @ticket 64404 + * + * @covers ::wp_schedule_event + * @covers ::wp_reschedule_event + */ + public function test_zero_schedule_interval_returns_error() { + add_filter( + 'cron_schedules', + static function ( $schedules ) { + $schedules['zero_interval'] = array( + 'interval' => 0, + 'display' => 'Zero interval', + ); + return $schedules; + } + ); + + $event = wp_schedule_event( time(), 'zero_interval', 'hook', array(), true ); + $this->assertWPError( $event ); + $this->assertSame( 'invalid_interval', $event->get_error_code() ); + + $rescheduled_event = wp_reschedule_event( time(), 'zero_interval', 'hook', array(), true ); + $this->assertWPError( $rescheduled_event ); + $this->assertSame( 'invalid_interval', $rescheduled_event->get_error_code() ); + } + + /** + * @ticket 64404 + * + * @covers ::wp_schedule_event + * @covers ::wp_reschedule_event + */ + public function test_non_numeric_schedule_interval_returns_error() { + add_filter( + 'cron_schedules', + static function ( $schedules ) { + $schedules['non_numeric_interval_string'] = array( + 'interval' => 'invalid', + 'display' => 'Non numeric interval (string)', + ); + $schedules['non_numeric_interval_null'] = array( + 'interval' => null, + 'display' => 'Non numeric interval (null)', + ); + return $schedules; + } + ); + + $string_event = wp_schedule_event( time(), 'non_numeric_interval_string', 'hook', array(), true ); + $this->assertWPError( $string_event ); + $this->assertSame( 'invalid_interval', $string_event->get_error_code() ); + + $string_rescheduled_event = wp_reschedule_event( time(), 'non_numeric_interval_string', 'hook', array(), true ); + $this->assertWPError( $string_rescheduled_event ); + $this->assertSame( 'invalid_interval', $string_rescheduled_event->get_error_code() ); + + $null_event = wp_schedule_event( time(), 'non_numeric_interval_null', 'hook', array(), true ); + $this->assertWPError( $null_event ); + $this->assertSame( 'invalid_interval', $null_event->get_error_code() ); + + $null_rescheduled_event = wp_reschedule_event( time(), 'non_numeric_interval_null', 'hook', array(), true ); + $this->assertWPError( $null_rescheduled_event ); + $this->assertSame( 'invalid_interval', $null_rescheduled_event->get_error_code() ); + } + /** * @ticket 49961 *