mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 02:15:42 +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:
		| @@ -355,52 +355,63 @@ static WebPMuxError MuxAddFrameTileInternal(WebPMux* const mux, uint32_t nth, | ||||
|   err = GetImageData(data, size, &vp8_data, &vp8_size, NULL, NULL); | ||||
|   if (err != WEBP_MUX_OK) return err; | ||||
|  | ||||
|   ChunkInit(&chunk); | ||||
|   MuxImageInit(&wpi); | ||||
|  | ||||
|   if (has_alpha) { | ||||
|     // Add alpha chunk. | ||||
|     ChunkInit(&chunk); | ||||
|     err = ChunkAssignDataImageInfo(&chunk, alpha_data, alpha_size, NULL, | ||||
|                                    copy_data, kChunks[ALPHA_ID].chunkTag); | ||||
|     if (err != WEBP_MUX_OK) return err; | ||||
|     err = ChunkSetNth(&chunk, &wpi.alpha_, 1); | ||||
|     if (err != WEBP_MUX_OK) return err; | ||||
|     ChunkInit(&chunk);  // chunk owned by wpi.alpha_ now. | ||||
|   } | ||||
|  | ||||
|   // Create image_info object. | ||||
|   image_info = CreateImageInfo(x_offset, y_offset, duration, vp8_data, | ||||
|                                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. | ||||
|   ChunkInit(&chunk); | ||||
|   err = ChunkAssignDataImageInfo(&chunk, vp8_data, vp8_size, image_info, | ||||
|                                  copy_data, kChunks[IMAGE_ID].chunkTag); | ||||
|   if (err != WEBP_MUX_OK) goto Err; | ||||
|   image_info = NULL;  // Owned by 'chunk' now. | ||||
|   err = ChunkSetNth(&chunk, &wpi.vp8_, 1); | ||||
|   if (err != WEBP_MUX_OK) goto Err; | ||||
|   ChunkInit(&chunk);  // chunk owned by wpi.vp8_ now. | ||||
|  | ||||
|   // Create frame/tile data from image_info. | ||||
|   err = CreateDataFromImageInfo(image_info, is_frame, &frame_tile_data, | ||||
|                                 &frame_tile_data_size); | ||||
|   err = CreateDataFromImageInfo(wpi.vp8_->image_info_, is_frame, | ||||
|                                 &frame_tile_data, &frame_tile_data_size); | ||||
|   if (err != WEBP_MUX_OK) goto Err; | ||||
|  | ||||
|   // Add frame/tile chunk (with copy_data = 1). | ||||
|   ChunkInit(&chunk); | ||||
|   err = ChunkAssignDataImageInfo(&chunk, frame_tile_data, frame_tile_data_size, | ||||
|                                  NULL, 1, tag); | ||||
|   if (err != WEBP_MUX_OK) goto Err; | ||||
|   free(frame_tile_data); | ||||
|   frame_tile_data = NULL; | ||||
|   err = ChunkSetNth(&chunk, &wpi.header_, 1); | ||||
|   if (err != WEBP_MUX_OK) goto Err; | ||||
|  | ||||
|   free(frame_tile_data); | ||||
|   ChunkInit(&chunk);  // chunk owned by wpi.header_ now. | ||||
|  | ||||
|   // 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. | ||||
|   free(image_info); | ||||
|   free(frame_tile_data); | ||||
|   ChunkRelease(&chunk); | ||||
|   MuxImageRelease(&wpi); | ||||
|   return err; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -153,6 +153,9 @@ WebPMuxError ChunkAssignDataImageInfo(WebPChunk* chunk, const uint8_t* data, | ||||
| WebPMuxError ChunkSetNth(const WebPChunk* chunk, WebPChunk** chunk_list, | ||||
|                          uint32_t nth); | ||||
|  | ||||
| // Releases chunk and returns chunk->next_. | ||||
| WebPChunk* ChunkRelease(WebPChunk* const chunk); | ||||
|  | ||||
| // Deletes given chunk & returns chunk->next_. | ||||
| WebPChunk* ChunkDelete(WebPChunk* const chunk); | ||||
|  | ||||
| @@ -174,6 +177,9 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst); | ||||
| // Initialize. | ||||
| 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. | ||||
| // 'wpi' can be NULL. | ||||
| WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi); | ||||
|   | ||||
| @@ -47,8 +47,7 @@ void ChunkInit(WebPChunk* const chunk) { | ||||
|   chunk->next_ = NULL; | ||||
| } | ||||
|  | ||||
| // Releases chunk and returns chunk->next_. | ||||
| static WebPChunk* ChunkRelease(WebPChunk* const chunk) { | ||||
| WebPChunk* ChunkRelease(WebPChunk* const chunk) { | ||||
|   WebPChunk* next; | ||||
|   if (chunk == NULL) return NULL; | ||||
|   free(chunk->image_info_); | ||||
| @@ -239,7 +238,7 @@ void MuxImageInit(WebPMuxImage* const wpi) { | ||||
|   wpi->next_ = NULL; | ||||
| } | ||||
|  | ||||
| static WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { | ||||
| WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { | ||||
|   WebPMuxImage* next; | ||||
|   if (wpi == NULL) return NULL; | ||||
|   ChunkDelete(wpi->header_); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user