Skip to content

gh-117534: Add checking for input parameter in iso_to_ymd #117543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 9, 2024

Conversation

Vlad4896
Copy link
Contributor

@Vlad4896 Vlad4896 commented Apr 4, 2024

Python terminates with core dumped on the following test:

import datetime

y = datetime.datetime.fromisoformat('0000W25')
print(y)

The test result:

python: ./Modules/_datetimemodule.c:290: days_before_year: Assertion `year >= 1' failed.
Aborted (core dumped)

The issue happened due to lack of checking for input parameters in iso_to_ymd().

@ghost
Copy link

ghost commented Apr 4, 2024

All commit authors signed the Contributor License Agreement.
CLA signed

@bedevere-app
Copy link

bedevere-app bot commented Apr 4, 2024

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@@ -416,6 +416,9 @@ 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) {
if (iso_year <= 0) {
return -2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-2 means a specific kind of error (wrong week).

I think that the year value should be checked before calling iso_to_ymd(). It is already checked in one case, but not in other.

Please add tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the back trace, the year value is taken from the string at parse_iso format_date() (the caller of the iso_to_umd()). Do you recommend check it in parse_iso format_date() and return -1 (-1: Failed to parse date component)?

#10 0x00007ffff7e3d7d6 in iso_to_ymd (iso_year=0, iso_week=25, iso_day=1, year=year@entry=0x7fffffffd71c, month=month@entry=0x7fffffffd720, day=day@entry=0x7fffffffd724)
    at ./Modules/_datetimemodule.c:440
#11 0x00007ffff7e3d998 in parse_isoformat_date (dtstr=dtstr@entry=0x7ffff74dd328 "0000W25", len=len@entry=7, year=year@entry=0x7fffffffd71c, month=month@entry=0x7fffffffd720, 
    day=day@entry=0x7fffffffd724) at ./Modules/_datetimemodule.c:803
#12 0x00007ffff7e479c0 in datetime_fromisoformat (cls=0x7ffff7e58000 <PyDateTime_DateTimeType>, dtstr=0x7ffff74dd300) at ./Modules/_datetimemodule.c:5506

Do you mean add testcase to 'def test_fromisoformat_date_examples(self)' ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, there are two calls of iso_to_umd(). In one case the year value is validated before calling iso_to_umd(), in other case it is not validated. We should either move the validation into iso_to_umd() (and introduce a special error code for this), or always validate the year value before calling iso_to_umd().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for comments. The fix is updated accordingly.
Also I added the test case to Lib/test/datetimetester.py.

@bedevere-app
Copy link

bedevere-app bot commented Apr 5, 2024

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@pganssle
Copy link
Member

pganssle commented Apr 5, 2024

Thanks for this, and good noticing this edge case!

What you have so far looks good to me, other than the NEWS entry.

I haven't been able to test it out, but does this also work in the pure Python version? Looks like that version may already have logic to deal with this, whereas the equivalent logic in _datetimemodule.c is in date_fromisocalendar.

@bedevere-app
Copy link

bedevere-app bot commented Apr 8, 2024

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Apr 8, 2024

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@Vlad4896
Copy link
Contributor Author

Vlad4896 commented Apr 8, 2024

Thanks for this, and good noticing this edge case!

What you have so far looks good to me, other than the NEWS entry.

I haven't been able to test it out, but does this also work in the pure Python version? Looks like that version may already have logic to deal with this, whereas the equivalent logic in _datetimemodule.c is in date_fromisocalendar.

I've added NEWS entry.
Could you please clarify, what do you mean "work in the pure Python version"?

Copy link
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please clarify, what do you mean "work in the pure Python version"?

datetime is a PEP 399 module, meaning there are two implementations, _pydatetime (which is written entirely in Python, and _datetimemodule.c, which is written in C. Most changes need to update both versions, because the logic is supposed to be identical.

In this case, I think it's OK, because the Python version already does the right thing because of the way the code is organized. That said, I tried to run this today and it looks like the core dump only happens if the code is compiled with assertions on — which by default it is not — so I think the severity of this bug is not as bad as I had feared.

Overall, I think this is a good patch. It brings the C code more in line with the Python code by unifying the error handling for invalid years, and prevents us from relying on an accidental feature of the way this was being parsed. I made two suggestions in the comments in-line, and if you want you can add yourself to the ACKS file, but other than that, if the CI passes after the changes, this is looking good to merge, assuming @serhiy-storchaka doesn't have any objections.

@bedevere-app
Copy link

bedevere-app bot commented Apr 8, 2024

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Copy link
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, other than moving your name around in the ACKS list.

@serhiy-storchaka Any other comments, or should we merge?

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@pganssle pganssle merged commit d5f1139 into python:main Apr 9, 2024
@pganssle pganssle added the needs backport to 3.12 only security fixes label Apr 9, 2024
@miss-islington-app
Copy link

Thanks @Vlad4896 for the PR, and @pganssle for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Apr 9, 2024
…onGH-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 d5f1139)

Co-authored-by: Vlad4896 <[email protected]>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
@bedevere-app
Copy link

bedevere-app bot commented Apr 9, 2024

GH-117689 is a backport of this pull request to the 3.12 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.12 only security fixes label Apr 9, 2024
pganssle pushed a commit that referenced this pull request Apr 9, 2024
…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 d5f1139)

Co-authored-by: Vlad4896 <[email protected]>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
diegorusso pushed a commit to diegorusso/cpython that referenced this pull request Apr 17, 2024
…on#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.

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants