diff options
author | Jyrki Muukkonen <jvtm@kruu.org> | 2023-03-28 09:51:31 +0300 |
---|---|---|
committer | Jyrki Muukkonen <jvtm@kruu.org> | 2023-03-28 11:04:22 +0300 |
commit | 781f8cdf9c6318e511a9459ac0a923502b455102 (patch) | |
tree | 86f44904f532107cff8961385cf226206186b266 | |
parent | d09feb650ba8d8af88b4f4e193b50e959bcb4a96 (diff) | |
download | jsonschema-781f8cdf9c6318e511a9459ac0a923502b455102.tar.gz |
fix: Python 3.11 date.fromisoformat() allows extra formats
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
* https://github.com/python/cpython/commit/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.
-rw-r--r-- | jsonschema/_format.py | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/jsonschema/_format.py b/jsonschema/_format.py index d274c5f..2231f5e 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -17,6 +17,8 @@ _RaisesType = typing.Union[ typing.Type[Exception], typing.Tuple[typing.Type[Exception], ...], ] +_RE_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$", re.ASCII) + class FormatChecker: """ @@ -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) |