Mailing List Archive

[3.12] gh-117534: Add checking for input parameter in iso_to_ymd (GH-117543) (#117689)
https://github.com/python/cpython/commit/af034dd150ca788ddae107ae5a1f8357f669de9f
commit: af034dd150ca788ddae107ae5a1f8357f669de9f
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
committer: pganssle <1377457+pganssle@users.noreply.github.com>
date: 2024-04-09T18:17:21Z
summary:

[3.12] gh-117534: Add checking for input parameter in iso_to_ymd (GH-117543) (#117689)

gh-117534: Add checking for input parameter in iso_to_ymd (GH-117543)

Moves the validation for invalid years in the C implementation of the `datetime` module into a common location between `fromisoformat` and `fromisocalendar`, which improves the error message and fixes a failed assertion when parsing invalid ISO 8601 years using one of the "ISO weeks" formats.

---------

(cherry picked from commit d5f1139c79525b4e7e4e8ad8c3e5fb831bbc3f28)

Co-authored-by: Vlad4896 <166005126+Vlad4896@users.noreply.github.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>

files:
A Misc/NEWS.d/next/C API/2024-04-08-09-44-29.gh-issue-117534.54ZE_n.rst
M Lib/test/datetimetester.py
M Misc/ACKS
M Modules/_datetimemodule.c

diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 55e061950ff280..404894ac36b91e 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -1908,6 +1908,10 @@ def test_fromisoformat_fails(self):
'2009-02-29', # Invalid leap day
'2019-W53-1', # No week 53 in 2019
'2020-W54-1', # No week 54
+ '0000-W25-1', # Invalid year
+ '10000-W25-1', # Invalid year
+ '2020-W25-0', # Invalid day-of-week
+ '2020-W25-8', # Invalid day-of-week
'2009\ud80002\ud80028', # Separators are surrogate codepoints
]

diff --git a/Misc/ACKS b/Misc/ACKS
index 371e9376582b2e..29a70b121faa4e 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -492,6 +492,7 @@ David Edelsohn
John Edmonds
Benjamin Edwards
Grant Edwards
+Vlad Efanov
Zvi Effron
John Ehresman
Tal Einat
diff --git a/Misc/NEWS.d/next/C API/2024-04-08-09-44-29.gh-issue-117534.54ZE_n.rst b/Misc/NEWS.d/next/C API/2024-04-08-09-44-29.gh-issue-117534.54ZE_n.rst
new file mode 100644
index 00000000000000..4b7dda610fc2b2
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2024-04-08-09-44-29.gh-issue-117534.54ZE_n.rst
@@ -0,0 +1,2 @@
+Improve validation logic in the C implementation of :meth:`datetime.fromisoformat`
+to better handle invalid years. Patch by Vlad Efanov.
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index c8dbc750b0ef5b..8552e42d8be5ee 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -392,6 +392,10 @@ iso_week1_monday(int year)
static int
iso_to_ymd(const int iso_year, const int iso_week, const int iso_day,
int *year, int *month, int *day) {
+ // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
+ if (iso_year < MINYEAR || iso_year > MAXYEAR) {
+ return -4;
+ }
if (iso_week <= 0 || iso_week >= 53) {
int out_of_range = 1;
if (iso_week == 53) {
@@ -738,7 +742,7 @@ parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month,
* -2: Inconsistent date separator usage
* -3: Failed to parse ISO week.
* -4: Failed to parse ISO day.
- * -5, -6: Failure in iso_to_ymd
+ * -5, -6, -7: Failure in iso_to_ymd
*/
const char *p = dtstr;
p = parse_digits(p, year, 4);
@@ -3097,15 +3101,13 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw)
return NULL;
}

- // Year is bounded to 0 < year < 10000 because 9999-12-31 is (9999, 52, 5)
- if (year < MINYEAR || year > MAXYEAR) {
- PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
- return NULL;
- }
-
int month;
int rv = iso_to_ymd(year, week, day, &year, &month, &day);

+ if (rv == -4) {
+ PyErr_Format(PyExc_ValueError, "Year is out of range: %d", year);
+ return NULL;
+ }

if (rv == -2) {
PyErr_Format(PyExc_ValueError, "Invalid week: %d", week);

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-leave@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: list-python-checkins@lists.gossamer-threads.com