-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-120754: Ensure _stat_atopen is cleared on fd change #125166
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
Changes from 4 commits
d57abd0
d2cb365
854ae91
c6da86e
0f64483
e2eebb0
5299a04
d749709
b429587
f08defa
e153d97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,6 +131,8 @@ | |
_Py_END_SUPPRESS_IPH | ||
Py_END_ALLOW_THREADS | ||
} | ||
PyMem_Free(self->stat_atopen); | ||
self->stat_atopen = NULL; | ||
if (err < 0) { | ||
errno = save_errno; | ||
PyErr_SetFromErrno(PyExc_OSError); | ||
|
@@ -258,7 +260,7 @@ | |
#elif !defined(MS_WINDOWS) | ||
int *atomic_flag_works = NULL; | ||
#endif | ||
int fstat_result; | ||
Check warning on line 263 in Modules/_io/fileio.c
|
||
int async_err = 0; | ||
|
||
#ifdef Py_DEBUG | ||
|
@@ -268,8 +270,9 @@ | |
if (self->fd >= 0) { | ||
if (self->closefd) { | ||
/* Have to close the existing file first. */ | ||
if (internal_close(self) < 0) | ||
if (internal_close(self) < 0) { | ||
return -1; | ||
} | ||
} | ||
else | ||
self->fd = -1; | ||
|
@@ -455,11 +458,17 @@ | |
#endif | ||
} | ||
|
||
PyMem_Free(self->stat_atopen); | ||
self->stat_atopen = PyMem_New(struct _Py_stat_struct, 1); | ||
if (self->stat_atopen == NULL) { | ||
PyErr_NoMemory(); | ||
goto error; | ||
/* FileIO.__init__ may be called on an already initialized object. Closing | ||
out the old fd (see: internal_close) should always nullify | ||
self->stat_atopen before this point. Just in case though, to prevent | ||
leaks, only allocate a new one if required. */ | ||
assert(self->stat_atopen == NULL) | ||
if (self->stat_atopen != NULL) { | ||
Check failure on line 466 in Modules/_io/fileio.c
|
||
|
||
self->stat_atopen = PyMem_New(struct _Py_stat_struct, 1); | ||
if (self->stat_atopen == NULL) { | ||
PyErr_NoMemory(); | ||
goto error; | ||
} | ||
} | ||
Py_BEGIN_ALLOW_THREADS | ||
fstat_result = _Py_fstat_noraise(self->fd, self->stat_atopen); | ||
|
@@ -523,10 +532,8 @@ | |
internal_close(self); | ||
_PyErr_ChainExceptions1(exc); | ||
} | ||
if (self->stat_atopen != NULL) { | ||
PyMem_Free(self->stat_atopen); | ||
self->stat_atopen = NULL; | ||
} | ||
PyMem_Free(self->stat_atopen); | ||
self->stat_atopen = NULL; | ||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
done: | ||
#ifdef MS_WINDOWS | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure which is preferred here. The Free + New back to back feels weird, but version with the conditional feels like "extra work/code that should never be executed" (but that the compiler / tools that run currently won't validate...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
if (ptr != NULL) free(ptr)
would be more regular and avoid the 4 lines long comment.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to that, dropped comment and simplified / back to always calling PyMem_New