Skip to content
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

bpo-34543: Fix SystemErrors and segfaults with uninitialized Structs #14777

Closed

Conversation

ZackerySpytz
Copy link
Contributor

@ZackerySpytz ZackerySpytz commented Jul 14, 2019

@ZackerySpytz
Copy link
Contributor Author

This patch uses a CHECK_INITIALIZED() macro (like what is done in Modules/_io), but there are other ways to fix this issue.

Copy link
Contributor

@aeros aeros left a comment

Choose a reason for hiding this comment

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

In order to test the changes, I attempted to recreate the segfault in the most current commit to cpython master and in your remote branch bpo-34543-struct-crashes.

cpython master:
image

image

PR branch:
image

For the version used for testing the latest cpython, I used the function test_segfault() on the second round in order to perform the test multiple times consecutively. The issue tracker reported similar problems with replication. The first round caused a TypeError, and the second one caused the segfault.

After performing test_segfault() 3 times consecutively in the PR's branch, ValueError was raised each time with the same message. As far as I can tell, this resolves the segfault issue and provides a significant improvement by raising a consistent exception each time.

Nicely done @ZackerySpytz, approved.

for meth in s.iter_unpack, s.pack, s.unpack, s.unpack_from:
self.assertRaises(ValueError, meth, b'0')
self.assertRaises(ValueError, s.pack_into, bytearray(1), 0, b'0')
self.assertRaises(ValueError, s.__sizeof__)
Copy link
Contributor

@aeros aeros Jul 15, 2019

Choose a reason for hiding this comment

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

Also, realized this after submitting the approval. This is quite minor, and I still approve of the PR either way. Instead of using s.__sizeof__, I would recommend using sys.getsizeof(s):

Suggested change
self.assertRaises(ValueError, s.__sizeof__)
self.assertRaises(ValueError, sys.getsizeof(s))

In general, it seems to be preferable to use functions instead of directly accessing the special object attributes when possible. If you had a specific reason for not using sys.getsizeof(), let me know. Here's the a link to the function defintion and the docs. I looked over it, but I'm not very experienced with the python c-api. I mostly rely on the docs when it comes to the modules implemented in c.

@aeros
Copy link
Contributor

aeros commented Jul 15, 2019

Also, this should probably be backported to previous versions. The code sample I used was the same from 3.7 with no noticeable difference in behavior prior to this patch: https://bugs.python.org/msg324498.

@brettcannon brettcannon added the type-bug An unexpected behavior, bug, or error label Jul 15, 2019
@jdemeyer
Copy link
Contributor

Wouldn't it make more sense to ensure that the invalid objects can't be created in the first place, by doing the initialization in __new__ instead of __init__?

@kumaraditya303
Copy link
Contributor

Superseded by #94532

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting core review type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants