-
-
Notifications
You must be signed in to change notification settings - Fork 32k
[2.7] bpo-36149 Fix potential use of uninitialized memory in cPickle #12105
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
Conversation
…ory on truncated pickles read from FILE*s.
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.
This is exactly why you shouldn't put all your logic in the "condition" of one if-statement.
Modules/cPickle.c
Outdated
} | ||
int newchar; | ||
while (i < (self->buf_size - 1)) { | ||
if (feof(self->fp)) |
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.
Isn't this redundant with the check on line 593?
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.
I don't know, is it? I can never remember the guaranteed semantics of FILE*s, feof() and functions that return EOF (which can signal error). Since the original function used this, I kept this it in.
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.
My manpage says getc()
returns EOF on end-of-file and error, so that's why I believe this is subsumed by the next call.
Modules/cPickle.c
Outdated
@@ -607,6 +609,10 @@ readline_file(Unpicklerobject *self, char **s) | |||
self->buf = newbuf; | |||
self->buf_size = bigger; | |||
} | |||
done: |
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.
I find it a little weird that this section is down here when the only way you can get to it is to jump out of a twice nested loop above.
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.
In my mind the end of the function is the natural place to put this, because it makes clear that the outer loop doesn't end without this bit getting executed (barring error-returns).
Modules/cPickle.c
Outdated
goto done; | ||
if ((newchar = getc(self->fp)) == EOF) | ||
goto done; | ||
self->buf[i++] = newchar; |
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.
self->buf[i++] = (newchar == EOF) ? '\0' : newchar
maybe?
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.
Didn't you just complain about too much logic in a single statement? :)
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.
(I'm happy to change it if you prefer, but since this code is all blisfully gone in 3 and it isn't exactly performance-critical I'm not sure it really matters...)
I think you could resolve all my nits by writing:
Do you think that's clearer? |
(You could even bring back the |
The loop you're proposing makes it not write the newline to self->buf. I'm not sure if that really matters (because it depends on what the callers of readline_file do) but it certainly changes what readline_file does. |
Ooops. Maybe
then? |
instead of the end of the functoin.
Fine, if you want to hide the function exit in the inner loop, there you go :) |
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.
We must just have different C aesthetics.
@Yhg1s: Please replace |
|
FYI, the amd64 windows7 buidbot failure appears unrelated to this change (it's a test_urllibnet timeout failure). |
Fix potential use of uninitialized memory in cPickle when reading truncated pickles from FILE*s.
https://bugs.python.org/issue36149