Skip to content

Commit 68e5b60

Browse files
gh-152157: Reject empty fractions in _datetime.{date}time.fromisoformat (GH-152161)
(cherry picked from commit 112c69a) Co-authored-by: tonghuaroot (童话) <tonghuaroot@gmail.com> Co-authored-by: Stan Ulbrych <stan@python.org>
1 parent 7087839 commit 68e5b60

3 files changed

Lines changed: 24 additions & 8 deletions

File tree

Lib/test/datetimetester.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,6 +3581,10 @@ def test_fromisoformat_fails_datetime(self):
35813581
'2009-04-19T12:30:45.400 +02:30', # Space between ms and timezone (gh-130959)
35823582
'2009-04-19T12:30:45.400 ', # Trailing space (gh-130959)
35833583
'2009-04-19T12:30:45. 400', # Space before fraction (gh-130959)
3584+
'2009-04-19T12:30:45.+05:00', # Empty fraction before offset
3585+
'2009-04-19T12:30:45.-05:00', # Empty fraction before offset
3586+
'2009-04-19T12:30:45.Z', # Empty fraction before Z
3587+
'2009-04-19T12:30:45,+05:00', # Empty fraction (comma) before offset
35843588
]
35853589

35863590
for bad_str in bad_strs:
@@ -4837,6 +4841,10 @@ def test_fromisoformat_fails(self):
48374841
'12:30:45.400 +02:30', # Space between ms and timezone (gh-130959)
48384842
'12:30:45.400 ', # Trailing space (gh-130959)
48394843
'12:30:45. 400', # Space before fraction (gh-130959)
4844+
'12:30:45.+05:00', # Empty fraction before offset
4845+
'12:30:45.-05:00', # Empty fraction before offset
4846+
'12:30:45.Z', # Empty fraction before Z
4847+
'12:30:45,+05:00', # Empty fraction (comma) before offset
48404848
]
48414849

48424850
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+
The C implementations of :meth:`~datetime.datetime.fromisoformat` and :meth:`~datetime.time.fromisoformat`
2+
now reject a decimal separator that is not followed by any
3+
fractional digit before a timezone designator.

Modules/_datetimemodule.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,16 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
10311031
has_separator = (c == ':');
10321032
}
10331033

1034-
if (p >= p_end) {
1034+
if (c == '.' || c == ',') {
1035+
if (i < 2) {
1036+
return -3; // Decimal mark on hour or minute
1037+
}
1038+
if (p >= p_end) {
1039+
return -3; // Decimal mark not followed by any digit
1040+
}
1041+
break;
1042+
}
1043+
else if (p >= p_end) {
10351044
return c != '\0';
10361045
}
10371046
else if (has_separator && (c == ':')) {
@@ -1040,14 +1049,10 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour,
10401049
}
10411050
continue;
10421051
}
1043-
else if (c == '.' || c == ',') {
1044-
if (i < 2) {
1045-
return -3; // Decimal mark on hour or minute
1046-
}
1047-
break;
1048-
} else if (!has_separator) {
1052+
else if (!has_separator) {
10491053
--p;
1050-
} else {
1054+
}
1055+
else {
10511056
return -4; // Malformed time separator
10521057
}
10531058
}

0 commit comments

Comments
 (0)