From cc3497b5e92d27c4fd81fb300b7b98cfecb18ee8 Mon Sep 17 00:00:00 2001 From: MGatner Date: Tue, 12 Jan 2021 15:00:18 +0000 Subject: [PATCH 1/2] Catch DateTime failure --- system/I18n/Exceptions/I18nException.php | 13 +++++++++++++ system/I18n/Time.php | 5 ++++- system/Language/en/Time.php | 1 + tests/system/I18n/TimeTest.php | 11 +++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/system/I18n/Exceptions/I18nException.php b/system/I18n/Exceptions/I18nException.php index 448e4b676ace..8ccaf8baa743 100644 --- a/system/I18n/Exceptions/I18nException.php +++ b/system/I18n/Exceptions/I18nException.php @@ -18,6 +18,19 @@ */ class I18nException extends FrameworkException { + /** + * Thrown when createFromFormat fails to receive a valid + * DateTime back from DateTime::createFromFormat. + * + * @param string $format + * + * @return static + */ + public static function forInvalidFormat(string $format) + { + return new static(lang('Time.invalidFormat', [$format])); + } + /** * Thrown when the numeric representation of the month falls * outside the range of allowed months. diff --git a/system/I18n/Time.php b/system/I18n/Time.php index 4d7214fbb3c7..660e5cc28c22 100644 --- a/system/I18n/Time.php +++ b/system/I18n/Time.php @@ -277,7 +277,10 @@ public static function create(int $year = null, int $month = null, int $day = nu */ public static function createFromFormat($format, $datetime, $timeZone = null) { - $date = parent::createFromFormat($format, $datetime); + if (! $date = parent::createFromFormat($format, $datetime)) + { + throw I18nException::forInvalidFormat($format); + } return new Time($date->format('Y-m-d H:i:s'), $timeZone); } diff --git a/system/Language/en/Time.php b/system/Language/en/Time.php index f92c504a07ab..47117b20d9b8 100644 --- a/system/Language/en/Time.php +++ b/system/Language/en/Time.php @@ -11,6 +11,7 @@ // Time language settings return [ + 'invalidFormat' => '"{0}" is not a valid datetime format', 'invalidMonth' => 'Months must be between 1 and 12. Given: {0}', 'invalidDay' => 'Days must be between 1 and 31. Given: {0}', 'invalidOverDay' => 'Days must be between 1 and {0}. Given: {1}', diff --git a/tests/system/I18n/TimeTest.php b/tests/system/I18n/TimeTest.php index 839e23779f1c..da5d6b09ea95 100644 --- a/tests/system/I18n/TimeTest.php +++ b/tests/system/I18n/TimeTest.php @@ -1,6 +1,7 @@ assertCloseEnoughString(date('2017-01-15 H:i:s'), $time->toDateTimeString()); } + public function testCreateFromFormatWithInvalidFormat() + { + $format = 'foobar'; + + $this->expectException(I18nException::class); + $this->expectExceptionMessage(lang('Time.invalidFormat', [$format])); + + $time = Time::createFromFormat($format, 'America/Chicago'); + } + public function testCreateFromTimestamp() { $time = Time::createFromTimestamp(strtotime('2017-03-18 midnight')); From fab0a6634f8dab502e1621b7e7000e530f850eba Mon Sep 17 00:00:00 2001 From: MGatner Date: Tue, 12 Jan 2021 15:17:28 +0000 Subject: [PATCH 2/2] Lock PHPStan --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 412352408c03..c1769fba21b2 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "codeigniter4/codeigniter4-standard": "^1.0", "fakerphp/faker": "^1.9", "mikey179/vfsstream": "^1.6", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "0.12.65", "phpunit/phpunit": "^8.5 || ^9.1", "predis/predis": "^1.1", "rector/rector": "^0.8",