diff --git a/src/mux/muxedit.c b/src/mux/muxedit.c index 105db013..eac725ac 100644 --- a/src/mux/muxedit.c +++ b/src/mux/muxedit.c @@ -39,12 +39,6 @@ WebPMux* WebPNewInternal(int version) { } } -static void DeleteAllChunks(WebPChunk** const chunk_list) { - while (*chunk_list) { - *chunk_list = ChunkDelete(*chunk_list); - } -} - // Delete all images in 'wpi_list'. static void DeleteAllImages(WebPMuxImage** const wpi_list) { while (*wpi_list != NULL) { @@ -55,12 +49,12 @@ static void DeleteAllImages(WebPMuxImage** const wpi_list) { static void MuxRelease(WebPMux* const mux) { if (mux == NULL) return; DeleteAllImages(&mux->images_); - DeleteAllChunks(&mux->vp8x_); - DeleteAllChunks(&mux->iccp_); - DeleteAllChunks(&mux->anim_); - DeleteAllChunks(&mux->exif_); - DeleteAllChunks(&mux->xmp_); - DeleteAllChunks(&mux->unknown_); + ChunkListDelete(&mux->vp8x_); + ChunkListDelete(&mux->iccp_); + ChunkListDelete(&mux->anim_); + ChunkListDelete(&mux->exif_); + ChunkListDelete(&mux->xmp_); + ChunkListDelete(&mux->unknown_); } void WebPMuxDelete(WebPMux* mux) { @@ -583,16 +577,6 @@ static WebPMuxError MuxCleanup(WebPMux* const mux) { return WEBP_MUX_OK; } -// Total size of a list of chunks. -static size_t ChunkListDiskSize(const WebPChunk* chunk_list) { - size_t size = 0; - while (chunk_list != NULL) { - size += ChunkDiskSize(chunk_list); - chunk_list = chunk_list->next_; - } - return size; -} - // Total size of a list of images. static size_t ImageListDiskSize(const WebPMuxImage* wpi_list) { size_t size = 0; diff --git a/src/mux/muxi.h b/src/mux/muxi.h index 20c12e8f..995e3f28 100644 --- a/src/mux/muxi.h +++ b/src/mux/muxi.h @@ -48,6 +48,7 @@ struct WebPMuxImage { WebPChunk* header_; // Corresponds to WEBP_CHUNK_ANMF/WEBP_CHUNK_FRGM. WebPChunk* alpha_; // Corresponds to WEBP_CHUNK_ALPHA. WebPChunk* img_; // Corresponds to WEBP_CHUNK_IMAGE. + WebPChunk* unknown_; // Corresponds to WEBP_CHUNK_UNKNOWN. int width_; int height_; int has_alpha_; // Through ALPH chunk or as part of VP8L. @@ -136,6 +137,9 @@ WebPChunk* ChunkRelease(WebPChunk* const chunk); // Deletes given chunk & returns chunk->next_. WebPChunk* ChunkDelete(WebPChunk* const chunk); +// Deletes all chunks in the given chunk list. +void ChunkListDelete(WebPChunk** const chunk_list); + // Returns size of the chunk including chunk header and padding byte (if any). static WEBP_INLINE size_t SizeWithPadding(size_t chunk_size) { return CHUNK_HEADER_SIZE + ((chunk_size + 1) & ~1U); @@ -148,6 +152,9 @@ static WEBP_INLINE size_t ChunkDiskSize(const WebPChunk* chunk) { return SizeWithPadding(data_size); } +// Total size of a list of chunks. +size_t ChunkListDiskSize(const WebPChunk* chunk_list); + // Write out the given list of chunks into 'dst'. uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst); diff --git a/src/mux/muxinternal.c b/src/mux/muxinternal.c index 56b2fcfe..0a620ec9 100644 --- a/src/mux/muxinternal.c +++ b/src/mux/muxinternal.c @@ -187,6 +187,12 @@ WebPChunk* ChunkDelete(WebPChunk* const chunk) { return next; } +void ChunkListDelete(WebPChunk** const chunk_list) { + while (*chunk_list != NULL) { + *chunk_list = ChunkDelete(*chunk_list); + } +} + //------------------------------------------------------------------------------ // Chunk serialization methods. @@ -211,6 +217,15 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) { return dst; } +size_t ChunkListDiskSize(const WebPChunk* chunk_list) { + size_t size = 0; + while (chunk_list != NULL) { + size += ChunkDiskSize(chunk_list); + chunk_list = chunk_list->next_; + } + return size; +} + //------------------------------------------------------------------------------ // Life of a MuxImage object. @@ -225,6 +240,7 @@ WebPMuxImage* MuxImageRelease(WebPMuxImage* const wpi) { ChunkDelete(wpi->header_); ChunkDelete(wpi->alpha_); ChunkDelete(wpi->img_); + ChunkListDelete(&wpi->unknown_); next = wpi->next_; MuxImageInit(wpi); @@ -356,6 +372,7 @@ size_t MuxImageDiskSize(const WebPMuxImage* const wpi) { if (wpi->header_ != NULL) size += ChunkDiskSize(wpi->header_); if (wpi->alpha_ != NULL) size += ChunkDiskSize(wpi->alpha_); if (wpi->img_ != NULL) size += ChunkDiskSize(wpi->img_); + if (wpi->unknown_ != NULL) size += ChunkListDiskSize(wpi->unknown_); return size; } @@ -387,6 +404,7 @@ uint8_t* MuxImageEmit(const WebPMuxImage* const wpi, uint8_t* dst) { } if (wpi->alpha_ != NULL) dst = ChunkEmit(wpi->alpha_, dst); if (wpi->img_ != NULL) dst = ChunkEmit(wpi->img_, dst); + if (wpi->unknown_ != NULL) dst = ChunkListEmit(wpi->unknown_, dst); return dst; } diff --git a/src/mux/muxread.c b/src/mux/muxread.c index a30508e3..03259d9d 100644 --- a/src/mux/muxread.c +++ b/src/mux/muxread.c @@ -147,6 +147,11 @@ static int MuxImageParse(const WebPChunk* const chunk, int copy_data, if (!MuxImageFinalize(wpi)) goto Fail; wpi->is_partial_ = 0; // wpi is completely filled. break; + case WEBP_CHUNK_UNKNOWN: + if (wpi->is_partial_) goto Fail; // Encountered an unknown chunk + // before some image chunks. + if (ChunkSetNth(&subchunk, &wpi->unknown_, 0) != WEBP_MUX_OK) goto Fail; + break; default: goto Fail; break;