-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Various checks on malloc #1781
Various checks on malloc #1781
Conversation
Changes Unknown when pulling 0564fb8 on wiredfool:malloc_check into * on python-pillow:master*. |
int n, i; | ||
int bands; | ||
Py_ssize_t n; | ||
int i, bands; |
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.
Should i
also be Py_ssize_t
?
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.
No, n is set to constant values well within the range of int in different locations in this function, and i counts up to that. The reason that n is a Py_ssize_t is that it's address is passed as an argument to getlist, which needs it to be a Py_ssize_t to match the result type of the python get sequence length function.
👍 |
0239830
to
29ab316
Compare
undone -
|
e88ca01
to
bdd9b93
Compare
@homm Can you take a look at this PR and comment? |
Ok. I will in couple of days. |
…nt about leaking memory from prior to when we had the cleanup mechanisim
…er uses of xsize/ysize
In general, I'm against replacing I will take a close look at every case later. |
My argument for calloc is:
I think that the only possible drawback is performance, but from my reading elsewhere calloc is likely faster than malloc + memset, and not significantly slower than malloc due to tricks that can be played with page mapping. |
Also, when looking at this, I think there's a significant speed gain to be made for larger images by combining I think it would be relatively transparent to the rest of the code if: |
Thinking about this long time, haven't implemented yet :) You are right that it should be transparent for most of C code except the code which directly uses |
I haven't researched, but my thought are optimal block size can be about: block_size = 2 * 2**20
mem_size = ((block_size + line_size - 1) // line_size) * line_size |
Looks like the only call to it is through the _imaging.c new_block interface, from ImageTk.py. Which bypasses the threshold check to ensure that they get one big chunk of memory to pass to tk. So the comment in ImagingNewBlock is wrong, and we should probably be returning an error where we're returning NULL from the overflow check. And ImagingDelete might need to be called on im to prevent a leak. |
@@ -376,12 +387,14 @@ getlist(PyObject* arg, int* length, const char* wrong_length, int type) | |||
} | |||
|
|||
n = PyObject_Length(arg); | |||
if (length && wrong_length && n != *length) { | |||
if (length && wrong_length && n != *length) { |
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.
why?
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.
Inadvertent
I've stopped in the middle. It's too large for one pass. |
No worries. I've done a quick benchmark on malloc vs calloc, where I opened and loaded a jpeg 100x, one of them was over the block limit and one was under. The difference between this branch (calloc) and master (malloc) is essentially lost in the noise. I'm seeing variances from run to run of ~1% with no clear pattern of one being faster. Calloc seems faster on the larger image, malloc on the smaller, but still pretty well within the noise level. |
Comments addressed. |
Ok, I finished with the rest of changes. |
I'd like feedback on this.
i think this is a good approach -- it follows the other changes that we've made to check for overflow on the mallocs. The biggest change is switching to calloc(n,size) instead of malloc(size) in some cases -- calloc does the multiplication, (is supposed to) check for overflow, and zeros the memory. I don't think that the zeroing is ever a bad thing, and there are some reports of the performance of calloc zeroing the memory faster than the memset that we use in a few places.
i will probably rebase/squash this prior to merging.