Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Lib/test/test_zoneinfo/test_zoneinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,10 @@ def test_invalid_tzstr(self):
"+11", # Unquoted alphanumeric
"GMT,M3.2.0/2,M11.1.0/3", # Transition rule but no DST
"GMT0+11,M3.2.0/2,M11.1.0/3", # Unquoted alphanumeric in DST
# Unquoted abbreviation with embedded or leading whitespace
"AB C3",
" A B 3",
"AAA4BB B,J60/2,J300/2", # Embedded whitespace in DST
"PST8PDT,M3.2.0/2", # Only one transition rule
# Invalid offset hours
"AAA168",
Expand Down Expand Up @@ -1222,6 +1226,29 @@ def test_invalid_tzstr(self):
with self.assertRaisesRegex(ValueError, tzstr_regex):
self.zone_from_tzstr(invalid_tzstr)

def test_invalid_tzstr_non_ascii_abbr(self):
# A non-ASCII letter reaches the parser via from_file()'s UTF-8 decode.
# It needs a separate test: it can't be ASCII-encoded for the shared
# invalid_tzstrs list, and the C error message holds the bytes repr.
Comment thread
StanFromIreland marked this conversation as resolved.
Outdated
tzstr = "ABÀC3"
footer = tzstr.encode("utf-8")

def from_footer():
Comment thread
StanFromIreland marked this conversation as resolved.
Outdated
zonefile = io.BytesIO(self._tzif_header)
zonefile.seek(0, 2)
zonefile.write(b"\x0A")
zonefile.write(footer)
zonefile.write(b"\x0A")
zonefile.seek(0)
return self.klass.from_file(zonefile, key=tzstr)

if self.module is py_zoneinfo:
expected = re.escape(tzstr)
else:
expected = re.escape(repr(footer))
with self.assertRaisesRegex(ValueError, expected):
from_footer()

@classmethod
def _populate_test_cases(cls):
# This method uses a somewhat unusual style in that it populates the
Expand Down
4 changes: 2 additions & 2 deletions Lib/zoneinfo/_zoneinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,11 @@ def _parse_tz_str(tz_str):

parser_re = re.compile(
r"""
(?P<std>[^<0-9:.+-]+|<[a-zA-Z0-9+-]+>)
(?P<std>[a-zA-Z]+|<[a-zA-Z0-9+-]+>)
Comment thread
StanFromIreland marked this conversation as resolved.
(?:
(?P<stdoff>[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?)
(?:
(?P<dst>[^0-9:.+-]+|<[a-zA-Z0-9+-]+>)
(?P<dst>[a-zA-Z]+|<[a-zA-Z0-9+-]+>)
(?P<dstoff>[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?)?
)? # dst
)? # stdoff
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix the pure-Python :mod:`zoneinfo` parser accepting an unquoted POSIX TZ
abbreviation that contains characters other than ASCII letters (for example an
embedded space), which the C implementation already rejects. Patch by
tonghuaroot.
Loading