mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-10 16:22:22 +03:00
Fix memory leak in TiffEncode
* If setimage errors out, the tiff client state was not freed.
This commit is contained in:
parent
a9bcd7db88
commit
e2e40c5456
|
@ -703,6 +703,8 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encoder->cleanup = ImagingLibTiffEncodeCleanup;
|
||||||
|
|
||||||
num_core_tags = sizeof(core_tags) / sizeof(int);
|
num_core_tags = sizeof(core_tags) / sizeof(int);
|
||||||
for (pos = 0; pos < tags_size; pos++) {
|
for (pos = 0; pos < tags_size; pos++) {
|
||||||
item = PyList_GetItemRef(tags, pos);
|
item = PyList_GetItemRef(tags, pos);
|
||||||
|
|
|
@ -929,6 +929,27 @@ ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ImagingLibTiffEncodeCleanup(ImagingCodecState state) {
|
||||||
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
|
TIFF *tiff = clientstate->tiff;
|
||||||
|
|
||||||
|
if (!tiff) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// TIFFClose in libtiff calls tif_closeproc and TIFFCleanup
|
||||||
|
if (clientstate->fp) {
|
||||||
|
// Python will manage the closing of the file rather than libtiff
|
||||||
|
// So only call TIFFCleanup
|
||||||
|
TIFFCleanup(tiff);
|
||||||
|
} else {
|
||||||
|
// When tif_closeproc refers to our custom _tiffCloseProc though,
|
||||||
|
// that is fine, as it does not close the file
|
||||||
|
TIFFClose(tiff);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes) {
|
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes) {
|
||||||
/* One shot encoder. Encode everything to the tiff in the clientstate.
|
/* One shot encoder. Encode everything to the tiff in the clientstate.
|
||||||
|
@ -1010,16 +1031,6 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
|
||||||
TRACE(("Encode Error, row %d\n", state->y));
|
TRACE(("Encode Error, row %d\n", state->y));
|
||||||
state->errcode = IMAGING_CODEC_BROKEN;
|
state->errcode = IMAGING_CODEC_BROKEN;
|
||||||
|
|
||||||
// TIFFClose in libtiff calls tif_closeproc and TIFFCleanup
|
|
||||||
if (clientstate->fp) {
|
|
||||||
// Python will manage the closing of the file rather than libtiff
|
|
||||||
// So only call TIFFCleanup
|
|
||||||
TIFFCleanup(tiff);
|
|
||||||
} else {
|
|
||||||
// When tif_closeproc refers to our custom _tiffCloseProc though,
|
|
||||||
// that is fine, as it does not close the file
|
|
||||||
TIFFClose(tiff);
|
|
||||||
}
|
|
||||||
if (!clientstate->fp) {
|
if (!clientstate->fp) {
|
||||||
free(clientstate->data);
|
free(clientstate->data);
|
||||||
}
|
}
|
||||||
|
@ -1036,22 +1047,11 @@ ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int byt
|
||||||
TRACE(("Error flushing the tiff"));
|
TRACE(("Error flushing the tiff"));
|
||||||
// likely reason is memory.
|
// likely reason is memory.
|
||||||
state->errcode = IMAGING_CODEC_MEMORY;
|
state->errcode = IMAGING_CODEC_MEMORY;
|
||||||
if (clientstate->fp) {
|
|
||||||
TIFFCleanup(tiff);
|
|
||||||
} else {
|
|
||||||
TIFFClose(tiff);
|
|
||||||
}
|
|
||||||
if (!clientstate->fp) {
|
if (!clientstate->fp) {
|
||||||
free(clientstate->data);
|
free(clientstate->data);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
TRACE(("Closing \n"));
|
|
||||||
if (clientstate->fp) {
|
|
||||||
TIFFCleanup(tiff);
|
|
||||||
} else {
|
|
||||||
TIFFClose(tiff);
|
|
||||||
}
|
|
||||||
// reset the clientstate metadata to use it to read out the buffer.
|
// reset the clientstate metadata to use it to read out the buffer.
|
||||||
clientstate->loc = 0;
|
clientstate->loc = 0;
|
||||||
clientstate->size = clientstate->eof; // redundant?
|
clientstate->size = clientstate->eof; // redundant?
|
||||||
|
|
|
@ -40,6 +40,8 @@ ImagingLibTiffInit(ImagingCodecState state, int fp, uint32_t offset);
|
||||||
extern int
|
extern int
|
||||||
ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
|
ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
|
||||||
extern int
|
extern int
|
||||||
|
ImagingLibTiffEncodeCleanup(ImagingCodecState state);
|
||||||
|
extern int
|
||||||
ImagingLibTiffMergeFieldInfo(
|
ImagingLibTiffMergeFieldInfo(
|
||||||
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length
|
ImagingCodecState state, TIFFDataType field_type, int key, int is_var_length
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user