mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-126883: Add check that timezone fields are in range for datetime.fromisoformat
(#127242)
It was previously possible to specify things like `+00:90:00` which would be equivalent to `+01:30:00`, but is not a valid ISO8601 string. --------- Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com> Co-authored-by: Paul Ganssle <1377457+pganssle@users.noreply.github.com>
This commit is contained in:
parent
8d490b3687
commit
71c42b778d
5 changed files with 63 additions and 9 deletions
|
@ -1088,6 +1088,7 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
|
|||
// -3: Failed to parse time component
|
||||
// -4: Failed to parse time separator
|
||||
// -5: Malformed timezone string
|
||||
// -6: Timezone fields are not in range
|
||||
|
||||
const char *p = dtstr;
|
||||
const char *p_end = dtstr + dtlen;
|
||||
|
@ -1134,6 +1135,11 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute,
|
|||
rv = parse_hh_mm_ss_ff(tzinfo_pos, p_end, &tzhour, &tzminute, &tzsecond,
|
||||
tzmicrosecond);
|
||||
|
||||
// Check if timezone fields are in range
|
||||
if (check_time_args(tzhour, tzminute, tzsecond, *tzmicrosecond, 0) < 0) {
|
||||
return -6;
|
||||
}
|
||||
|
||||
*tzoffset = tzsign * ((tzhour * 3600) + (tzminute * 60) + tzsecond);
|
||||
*tzmicrosecond *= tzsign;
|
||||
|
||||
|
@ -5039,6 +5045,9 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) {
|
|||
&tzoffset, &tzimicrosecond);
|
||||
|
||||
if (rv < 0) {
|
||||
if (rv == -6) {
|
||||
goto error;
|
||||
}
|
||||
goto invalid_string_error;
|
||||
}
|
||||
|
||||
|
@ -5075,6 +5084,9 @@ invalid_iso_midnight:
|
|||
invalid_string_error:
|
||||
PyErr_Format(PyExc_ValueError, "Invalid isoformat string: %R", tstr);
|
||||
return NULL;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5927,6 +5939,9 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr)
|
|||
len -= (p - dt_ptr);
|
||||
rv = parse_isoformat_time(p, len, &hour, &minute, &second,
|
||||
µsecond, &tzoffset, &tzusec);
|
||||
if (rv == -6) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (rv < 0) {
|
||||
goto invalid_string_error;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue