From 97b9745c850f9b0a53bf470715baf60dba41d930 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Mon, 9 Dec 2019 22:46:40 +0100 Subject: [PATCH] [Validator][ConstraintValidator] Safe fail on invalid timezones Co-authored-by: Scott Dawson --- .../Component/Validator/ConstraintValidator.php | 10 ++++++++-- .../Validator/Tests/ConstraintValidatorTest.php | 15 ++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index 93cca2ea74a5e..97515b5048502 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -87,8 +87,14 @@ protected function formatValue($value, $format = 0) { if (($format & self::PRETTY_DATE) && $value instanceof \DateTimeInterface) { if (class_exists('IntlDateFormatter')) { - $locale = \Locale::getDefault(); - $formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, $value->getTimezone()); + $formatter = new \IntlDateFormatter(\Locale::getDefault(), \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT); + + $timezone = $value->getTimezone(); + if ('Z' === $timezone->getName()) { + $timezone = new \DateTimeZone('UTC'); + } + + $formatter->setTimeZone($timezone); // neither the native nor the stub IntlDateFormatter support // DateTimeImmutable as of yet diff --git a/src/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php b/src/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php index 96af6f13eb4e7..de59fe42a890c 100644 --- a/src/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php @@ -22,12 +22,17 @@ final class ConstraintValidatorTest extends TestCase */ public function testFormatValue($expected, $value, $format = 0) { + $default = date_default_timezone_get(); + date_default_timezone_set('Europe/Moscow'); + $this->assertSame($expected, (new TestFormatValueConstraintValidator())->formatValueProxy($value, $format)); + + date_default_timezone_set($default); } public function formatValueProvider() { - $data = [ + return [ ['true', true], ['false', false], ['null', null], @@ -36,11 +41,11 @@ public function formatValueProvider() ['array', []], ['object', $toString = new TestToStringObject()], ['ccc', $toString, ConstraintValidator::OBJECT_TO_STRING], - ['object', $dateTime = (new \DateTimeImmutable('@0'))->setTimezone(new \DateTimeZone('UTC'))], - [class_exists(\IntlDateFormatter::class) ? 'Jan 1, 1970, 12:00 AM' : '1970-01-01 00:00:00', $dateTime, ConstraintValidator::PRETTY_DATE], + ['object', $dateTime = (new \DateTimeImmutable('1971-02-02T08:00:00'))->setTimezone(new \DateTimeZone('UTC'))], + [class_exists(\IntlDateFormatter::class) ? 'Oct 4, 2019, 11:02 AM' : '2019-10-04 11:02:03', new \DateTimeImmutable('2019-10-04T11:02:03+09:00'), ConstraintValidator::PRETTY_DATE], + [class_exists(\IntlDateFormatter::class) ? 'Feb 2, 1971, 8:00 AM' : '1971-02-02 08:00:00', $dateTime, ConstraintValidator::PRETTY_DATE], + [class_exists(\IntlDateFormatter::class) ? 'Jan 1, 1970, 6:00 AM' : '1970-01-01 6:00:00', (new \DateTimeImmutable('1970-01-01T06:00:00'))->setTimezone(new \DateTimeZone('Z')), ConstraintValidator::PRETTY_DATE], ]; - - return $data; } }