Skip to content

Commit

Permalink
fix: Python 3.11 date.fromisoformat() allows extra formats
Browse files Browse the repository at this point in the history
Python 3.11 and later allow additional ISO8601 formats in `datetime` module
ISO8601 parsing. These formats are not RFC3339 section 5.6 compliant.

Especially `datetime.date.fromisoformat()` now allows strings like:
 * `20230328` (2023-03-28)
 * `2022W527` (2023-01-01)
 * `2023-W01` (2023-01-02)
 * `2023-W13-2` (2023-03-28)

Fix by doing a regular expression check before passing the value to `datetime`
module. This made the original `.isascii()` check unnecessary.

See:
 * https://docs.python.org/3/whatsnew/3.11.html#datetime
 * python/cpython@1303f8c927
 * https://docs.python.org/3.11/library/datetime.html#datetime.date.fromisoformat
 * https://www.rfc-editor.org/rfc/rfc3339#section-5.6

Tests covering the invalid values to be sent to json-schema-org/JSON-Schema-Test-Suite

Fixes #1056.
  • Loading branch information
jvtm committed Mar 28, 2023
1 parent d09feb6 commit 781f8cd
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion jsonschema/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
typing.Type[Exception], typing.Tuple[typing.Type[Exception], ...],
]

_RE_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$", re.ASCII)


class FormatChecker:
"""
Expand Down Expand Up @@ -396,7 +398,10 @@ def is_regex(instance: object) -> bool:
def is_date(instance: object) -> bool:
if not isinstance(instance, str):
return True
return bool(instance.isascii() and datetime.date.fromisoformat(instance))
return bool(
_RE_DATE.fullmatch(instance)
and datetime.date.fromisoformat(instance)
)


@_checks_drafts(draft3="time", raises=ValueError)
Expand Down

0 comments on commit 781f8cd

Please sign in to comment.