mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
mux: plug some memory leaks on error
Make sure chunk->data and wpi are not leaked by MuxAddFrameTileInternal() in case of MEMORY_ERROR in ChunkSetNth(). Change-Id: Ie20e84b92f4bdcb7c3b94520f36b20dd2e730545
This commit is contained in:
parent
241ddd38e2
commit
b0d2fecf25
@ -355,52 +355,63 @@ static WebPMuxError MuxAddFrameTileInternal(WebPMux* const mux, uint32_t nth,
|
|||||||
err = GetImageData(data, size, &vp8_data, &vp8_size, NULL, NULL);
|
err = GetImageData(data, size, &vp8_data, &vp8_size, NULL, NULL);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
|
||||||
|
ChunkInit(&chunk);
|
||||||
MuxImageInit(&wpi);
|
MuxImageInit(&wpi);
|
||||||
|
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
// Add alpha chunk.
|
// Add alpha chunk.
|
||||||
ChunkInit(&chunk);
|
|
||||||
err = ChunkAssignDataImageInfo(&chunk, alpha_data, alpha_size, NULL,
|
err = ChunkAssignDataImageInfo(&chunk, alpha_data, alpha_size, NULL,
|
||||||
copy_data, kChunks[ALPHA_ID].chunkTag);
|
copy_data, kChunks[ALPHA_ID].chunkTag);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
err = ChunkSetNth(&chunk, &wpi.alpha_, 1);
|
err = ChunkSetNth(&chunk, &wpi.alpha_, 1);
|
||||||
if (err != WEBP_MUX_OK) return err;
|
if (err != WEBP_MUX_OK) return err;
|
||||||
|
ChunkInit(&chunk); // chunk owned by wpi.alpha_ now.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create image_info object.
|
// Create image_info object.
|
||||||
image_info = CreateImageInfo(x_offset, y_offset, duration, vp8_data,
|
image_info = CreateImageInfo(x_offset, y_offset, duration, vp8_data,
|
||||||
vp8_size);
|
vp8_size);
|
||||||
if (image_info == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (image_info == NULL) {
|
||||||
|
MuxImageRelease(&wpi);
|
||||||
|
return WEBP_MUX_MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Add image chunk.
|
// Add image chunk.
|
||||||
ChunkInit(&chunk);
|
|
||||||
err = ChunkAssignDataImageInfo(&chunk, vp8_data, vp8_size, image_info,
|
err = ChunkAssignDataImageInfo(&chunk, vp8_data, vp8_size, image_info,
|
||||||
copy_data, kChunks[IMAGE_ID].chunkTag);
|
copy_data, kChunks[IMAGE_ID].chunkTag);
|
||||||
if (err != WEBP_MUX_OK) goto Err;
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
image_info = NULL; // Owned by 'chunk' now.
|
||||||
err = ChunkSetNth(&chunk, &wpi.vp8_, 1);
|
err = ChunkSetNth(&chunk, &wpi.vp8_, 1);
|
||||||
if (err != WEBP_MUX_OK) goto Err;
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
ChunkInit(&chunk); // chunk owned by wpi.vp8_ now.
|
||||||
|
|
||||||
// Create frame/tile data from image_info.
|
// Create frame/tile data from image_info.
|
||||||
err = CreateDataFromImageInfo(image_info, is_frame, &frame_tile_data,
|
err = CreateDataFromImageInfo(wpi.vp8_->image_info_, is_frame,
|
||||||
&frame_tile_data_size);
|
&frame_tile_data, &frame_tile_data_size);
|
||||||
if (err != WEBP_MUX_OK) goto Err;
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
|
||||||
// Add frame/tile chunk (with copy_data = 1).
|
// Add frame/tile chunk (with copy_data = 1).
|
||||||
ChunkInit(&chunk);
|
|
||||||
err = ChunkAssignDataImageInfo(&chunk, frame_tile_data, frame_tile_data_size,
|
err = ChunkAssignDataImageInfo(&chunk, frame_tile_data, frame_tile_data_size,
|
||||||
NULL, 1, tag);
|
NULL, 1, tag);
|
||||||
if (err != WEBP_MUX_OK) goto Err;
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
free(frame_tile_data);
|
||||||
|
frame_tile_data = NULL;
|
||||||
err = ChunkSetNth(&chunk, &wpi.header_, 1);
|
err = ChunkSetNth(&chunk, &wpi.header_, 1);
|
||||||
if (err != WEBP_MUX_OK) goto Err;
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
ChunkInit(&chunk); // chunk owned by wpi.header_ now.
|
||||||
free(frame_tile_data);
|
|
||||||
|
|
||||||
// Add this WebPMuxImage to mux.
|
// Add this WebPMuxImage to mux.
|
||||||
return MuxImageSetNth(&wpi, &mux->images_, nth);
|
err = MuxImageSetNth(&wpi, &mux->images_, nth);
|
||||||
|
if (err != WEBP_MUX_OK) goto Err;
|
||||||
|
|
||||||
|
// All is well.
|
||||||
|
return WEBP_MUX_OK;
|
||||||
|
|
||||||
Err: // Something bad happened.
|
Err: // Something bad happened.
|
||||||
free(image_info);
|
free(image_info);
|
||||||
free(frame_tile_data);
|
free(frame_tile_data);
|
||||||
|
ChunkRelease(&chunk);
|
||||||
|
MuxImageRelease(&wpi);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +153,9 @@ WebPMuxError ChunkAssignDataImageInfo(WebPChunk* chunk, const uint8_t* data,
|
|||||||
WebPMuxError ChunkSetNth(const WebPChunk* chunk, WebPChunk** chunk_list,
|
WebPMuxError ChunkSetNth(const WebPChunk* chunk, WebPChunk** chunk_list,
|
||||||
uint32_t nth);
|
uint32_t nth);
|
||||||
|
|
||||||
|
// Releases chunk and returns chunk->next_.
|
||||||
|
WebPChunk* ChunkRelease(WebPChunk* const chunk);
|
||||||
|
|
||||||
// Deletes given chunk & returns chunk->next_.
|
// Deletes given chunk & returns chunk->next_.
|
||||||
WebPChunk* ChunkDelete(WebPChunk* const chunk);
|
WebPChunk* ChunkDelete(WebPChunk* const chunk);
|
||||||
|
|
||||||
@ -174,6 +177,9 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst);
|
|||||||
// Initialize.
|
// Initialize.
|
||||||
void MuxImageInit(WebPMuxImage* const wpi);
|
void MuxImageInit(WebPMuxImage* const wpi);
|
||||||
|
|
||||||
|
// Releases image 'wpi' and returns wpi->next.
|
||||||
|
WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi);
|
||||||
|
|
||||||
// Delete image 'wpi' and return the next image in the list or NULL.
|
// Delete image 'wpi' and return the next image in the list or NULL.
|
||||||
// 'wpi' can be NULL.
|
// 'wpi' can be NULL.
|
||||||
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
|
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi);
|
||||||
|
@ -47,8 +47,7 @@ void ChunkInit(WebPChunk* const chunk) {
|
|||||||
chunk->next_ = NULL;
|
chunk->next_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Releases chunk and returns chunk->next_.
|
WebPChunk* ChunkRelease(WebPChunk* const chunk) {
|
||||||
static WebPChunk* ChunkRelease(WebPChunk* const chunk) {
|
|
||||||
WebPChunk* next;
|
WebPChunk* next;
|
||||||
if (chunk == NULL) return NULL;
|
if (chunk == NULL) return NULL;
|
||||||
free(chunk->image_info_);
|
free(chunk->image_info_);
|
||||||
@ -239,7 +238,7 @@ void MuxImageInit(WebPMuxImage* const wpi) {
|
|||||||
wpi->next_ = NULL;
|
wpi->next_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
|
WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) {
|
||||||
WebPMuxImage* next;
|
WebPMuxImage* next;
|
||||||
if (wpi == NULL) return NULL;
|
if (wpi == NULL) return NULL;
|
||||||
ChunkDelete(wpi->header_);
|
ChunkDelete(wpi->header_);
|
||||||
|
Loading…
Reference in New Issue
Block a user