8000 [3.13] gh-130959: Reject whitespace in fractions, in pure Python `fro… · python/cpython@27fd328 · GitHub
[go: up one dir, main page]

Skip to content

Commit 27fd328

Browse files
vstinnermgorny
andauthored
[3.13] gh-130959: Reject whitespace in fractions, in pure Python fromisoformat() (#130962) (#131076)
gh-130959: Reject whitespace in fractions, in pure Python `fromisoformat()` (#130962) Fix the pure Python implementation of `fromisoformat()` to reject any non-digit characters, including whitespace, in the fractional part of time specification. This makes the behavior consistent with the C implementation, and prevents incorrect parsing of these fractions (e.g. `.400 ` would be misinterpreted as `.04`). Co-authored-by: Peter Bierma <zintensitydev@gmail.com> Co-authored-by: Paul Ganssle <1377457+pganssle@users.noreply.github.com> (cherry picked from commit 33494b4) Co-authored-by: Michał Górny <mgorny@gentoo.org>
1 parent 68a1591 commit 27fd328

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

Lib/_pydatetime.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ def _parse_hh_mm_ss_ff(tstr):
402402
raise ValueError("Invalid microsecond component")
403403
else:
404404
pos += 1
405+
if not all(map(_is_ascii_digit, tstr[pos:])):
406+
raise ValueError("Non-digit values in fraction")
405407

406408
len_remainder = len_str - pos
407409

@@ -413,9 +415,6 @@ def _parse_hh_mm_ss_ff(tstr):
413415
time_comps[3] = int(tstr[pos:(pos+to_parse)])
414416
if to_parse < 6:
415417
time_comps[3] *= _FRACTION_CORRECTION[to_parse-1]
416-
if (len_remainder > to_parse
417-
and not all(map(_is_ascii_digit, tstr[(pos+to_parse):]))):
418-
raise ValueError("Non-digit values in unparsed fraction")
419418

420419
return time_comps
421420

Lib/test/datetimetester.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3385,6 +3385,9 @@ def test_fromisoformat_fails_datetime(self):
33853385
'2009-04-19T12:30:45.123456-05:00a', # Extra text
33863386
'2009-04-19T12:30:45.123-05:00a', # Extra text
33873387
'2009-04-19T12:30:45-05:00a', # Extra text
3388+
'2009-04-19T12:30:45.400 +02:30', # Space between ms and timezone (gh-130959)
3389+
'2009-04-19T12:30:45.400 ', # Trailing space (gh-130959)
3390+
'2009-04-19T12:30:45. 400', # Space before fraction (gh-130959)
33883391
]
33893392

33903393
for bad_str in bad_strs:
@@ -4469,6 +4472,9 @@ def test_fromisoformat_fails(self):
44694472
'12:30:45.123456-', # Extra at end of microsecond time
44704473
'12:30:45.123456+', # Extra at end of microsecond time
44714474
'12:30:45.123456+12:00:30a', # Extra at end of full time
4475+
'12:30:45.400 +02:30', # Space between ms and timezone (gh-130959)
4476+
'12:30:45.400 ', # Trailing space (gh-130959)
4477+
'12:30:45. 400', # Space before fraction (gh-130959)
44724478
]
44734479

44744480
for bad_str in bad_strs:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix pure-Python implementation of :func:`datetime.time.fromisoformat` to reject
2+
times with spaces in fractional part (for example, ``12:34:56.400 +02:00``),
3+
matching the C implementation. Patch by Michał Gorny.

0 commit comments

Comments
 (0)
0