diff --git a/src/JsonSchema/Constraints/Drafts/Draft06/FormatConstraint.php b/src/JsonSchema/Constraints/Drafts/Draft06/FormatConstraint.php index ec61b73b..d8cc0e00 100644 --- a/src/JsonSchema/Constraints/Drafts/Draft06/FormatConstraint.php +++ b/src/JsonSchema/Constraints/Drafts/Draft06/FormatConstraint.php @@ -125,7 +125,11 @@ public function check(&$value, $schema = null, ?JsonPointer $path = null, $i = n private function validateDateTime(string $datetime, string $format): bool { - $dt = \DateTime::createFromFormat($format, $datetime); + try { + $dt = \DateTime::createFromFormat($format, $datetime); + } catch (\Throwable $e) { + return false; + } if (!$dt) { return false; diff --git a/src/JsonSchema/Constraints/Drafts/Draft07/FormatConstraint.php b/src/JsonSchema/Constraints/Drafts/Draft07/FormatConstraint.php index 8ddc879d..fd5474b6 100644 --- a/src/JsonSchema/Constraints/Drafts/Draft07/FormatConstraint.php +++ b/src/JsonSchema/Constraints/Drafts/Draft07/FormatConstraint.php @@ -149,7 +149,12 @@ private function validateDateTime(string $datetime, string $format): bool $input = sprintf('%s59%s', substr($datetime, 0, 6), substr($datetime, 8)); } - $dt = \DateTimeImmutable::createFromFormat($format, $input); + try { + $dt = \DateTimeImmutable::createFromFormat($format, $input); + } catch (\Throwable $e) { + return false; + } + if (!$dt) { return false; } diff --git a/src/JsonSchema/Constraints/Drafts/Draft2019/FormatConstraint.php b/src/JsonSchema/Constraints/Drafts/Draft2019/FormatConstraint.php index 5fb47c87..419f3cb2 100644 --- a/src/JsonSchema/Constraints/Drafts/Draft2019/FormatConstraint.php +++ b/src/JsonSchema/Constraints/Drafts/Draft2019/FormatConstraint.php @@ -140,7 +140,12 @@ private function validateDateTime(string $datetime, string $format): bool $input = sprintf('%s59%s', substr($datetime, 0, 6), substr($datetime, 8)); } - $dt = \DateTimeImmutable::createFromFormat($format, $input); + try { + $dt = \DateTimeImmutable::createFromFormat($format, $input); + } catch (\Throwable $e) { + return false; + } + if (!$dt) { return false; } diff --git a/src/JsonSchema/Constraints/FormatConstraint.php b/src/JsonSchema/Constraints/FormatConstraint.php index c38488dd..20fdb207 100644 --- a/src/JsonSchema/Constraints/FormatConstraint.php +++ b/src/JsonSchema/Constraints/FormatConstraint.php @@ -154,7 +154,11 @@ public function check(&$element, $schema = null, ?JsonPointer $path = null, $i = protected function validateDateTime($datetime, $format) { - $dt = \DateTime::createFromFormat($format, (string) $datetime); + try { + $dt = \DateTime::createFromFormat($format, (string) $datetime); + } catch (\Throwable $e) { + return false; + } if (!$dt) { return false; diff --git a/tests/Constraints/Draft06/FormatConstraintTest.php b/tests/Constraints/Draft06/FormatConstraintTest.php new file mode 100644 index 00000000..7be2849d --- /dev/null +++ b/tests/Constraints/Draft06/FormatConstraintTest.php @@ -0,0 +1,34 @@ +format = $format; + + $validator->check($string, $schema); + $this->assertCount(1, $validator->getErrors(), 'Expected 1 error'); + } + + public function getInvalidFormats(): Generator + { + yield 'Date-time format with value containing null byte' => ["2020-01-01T12:34:56\x00", 'date-time']; + + yield 'Date format with value containing null byte' => ["2020-01-01\x00", 'date']; + + yield 'Time format with value containing null byte' => ["13:37:00\x00", 'time']; + } +} diff --git a/tests/Constraints/Draft07/FormatConstraintTest.php b/tests/Constraints/Draft07/FormatConstraintTest.php new file mode 100644 index 00000000..fcf09b80 --- /dev/null +++ b/tests/Constraints/Draft07/FormatConstraintTest.php @@ -0,0 +1,34 @@ +format = $format; + + $validator->check($string, $schema); + $this->assertCount(1, $validator->getErrors(), 'Expected 1 error'); + } + + public function getInvalidFormats(): Generator + { + yield 'Date-time format with value containing null byte' => ["2020-01-01T12:34:56\x00", 'date-time']; + + yield 'Date format with value containing null byte' => ["2020-01-01\x00", 'date']; + + yield 'Time format with value containing null byte' => ["13:37:00\x00", 'time']; + } +} diff --git a/tests/Constraints/Draft2019/FormatConstraintTest.php b/tests/Constraints/Draft2019/FormatConstraintTest.php new file mode 100644 index 00000000..5c6b90d5 --- /dev/null +++ b/tests/Constraints/Draft2019/FormatConstraintTest.php @@ -0,0 +1,34 @@ +format = $format; + + $validator->check($string, $schema); + $this->assertCount(1, $validator->getErrors(), 'Expected 1 error'); + } + + public function getInvalidFormats(): Generator + { + yield 'Date-time format with value containing null byte' => ["2020-01-01T12:34:56\x00", 'date-time']; + + yield 'Date format with value containing null byte' => ["2020-01-01\x00", 'date']; + + yield 'Time format with value containing null byte' => ["13:37:00\x00", 'time']; + } +} diff --git a/tests/Constraints/FormatTest.php b/tests/Constraints/FormatConstraintTest.php similarity index 97% rename from tests/Constraints/FormatTest.php rename to tests/Constraints/FormatConstraintTest.php index 72471054..948bfd31 100644 --- a/tests/Constraints/FormatTest.php +++ b/tests/Constraints/FormatConstraintTest.php @@ -8,7 +8,7 @@ use JsonSchema\Constraints\Factory; use JsonSchema\Constraints\FormatConstraint; -class FormatTest extends BaseTestCase +class FormatConstraintTest extends BaseTestCase { /** @var bool */ protected $validateSchema = true; @@ -196,10 +196,12 @@ public function getInvalidFormats(): \Generator yield ['199-01-1', 'date']; yield ['2012-0-11', 'date']; yield ['2012-10-1', 'date']; + yield 'Date format with value containing null byte' => ["2020-01-01\x00", 'date']; yield ['24:01:00', 'time']; yield ['00:00:60', 'time']; yield ['25:00:00', 'time']; + yield 'Time format with value containing null byte' => ["13:37:00\x00", 'time']; yield ['invalid_value_2000-05-01T12:12:12Z', 'date-time']; yield ['2000-05-01T12:12:12Z_invalid_value', 'date-time'];