From edfb92ebffc2dac58dd56e79156f805470f79e2e Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Thu, 8 Feb 2018 23:12:26 +0100 Subject: [PATCH] Several changes to exception throwing and fixed several memory leaks. --- coders/heic.c | 116 ++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 65 deletions(-) diff --git a/coders/heic.c b/coders/heic.c index 4753fdbb4..0e0cd2d09 100644 --- a/coders/heic.c +++ b/coders/heic.c @@ -177,9 +177,13 @@ typedef struct _DataBuffer { #define ATOM(a,b,c,d) ((a << 24) + (b << 16) + (c << 8) + d) +#define ThrowImproperImageHeader(msg) { \ + (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError, \ + "ImproperImageHeader","`%s'",msg); \ +} #define ThrowAndReturn(msg) { \ - ThrowFileException(exception, CorruptImageError, "Bad image: " # msg, __func__); \ - return MagickFalse; \ + ThrowImproperImageHeader(msg) \ + return(MagickFalse); \ } inline static unsigned int readInt(const unsigned char* data) @@ -296,7 +300,7 @@ static MagickBooleanType ParseFullBox(Image *image, DataBuffer *db, } for (i = 0; i < MAX_ATOMS_IN_BOX && DBGetSize(db) > 0; i++) { - ParseAtom(image, db, ctx, exception); + (void) ParseAtom(image, db, ctx, exception); } return MagickTrue; @@ -309,7 +313,7 @@ static MagickBooleanType ParseBox(Image *image, DataBuffer *db, i; for (i = 0; i < MAX_ATOMS_IN_BOX && DBGetSize(db) > 0; i++) { - ParseAtom(image, db, ctx, exception); + (void) ParseAtom(image, db, ctx, exception); } return MagickTrue; @@ -445,15 +449,14 @@ static MagickBooleanType ParseIinfAtom(Image *image, DataBuffer *db, ctx->idsCount = count; ctx->itemInfo = (HEICItemInfo *)AcquireMagickMemory(sizeof(HEICItemInfo)*(count+1)); if (ctx->itemInfo == (HEICItemInfo *) NULL) - { - ThrowAndReturn("unable to allocate memory"); - } + ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", + image->filename); ResetMagickMemory(ctx->itemInfo, 0, sizeof(HEICItemInfo)*(count+1)); for (i = 0; i < count && DBGetSize(db) > 0; i++) { - ParseAtom(image, db, ctx, exception); + (void) ParseAtom(image, db, ctx, exception); } return MagickTrue; @@ -646,7 +649,7 @@ static MagickBooleanType ParseAtom(Image *image, DataBuffer *db, if (DBChop(&atomDb, db, atom_size - 8) != MagickTrue) { - ThrowAndReturn("unable to read atom"); + ThrowAndReturn("unable to read atom"); } status = MagickTrue; @@ -678,9 +681,9 @@ static MagickBooleanType ParseAtom(Image *image, DataBuffer *db, { ctx->idatSize = atom_size - 8; ctx->idat = (uint8_t *) AcquireMagickMemory(ctx->idatSize); - if (ctx->idat == NULL) { - ThrowAndReturn("unable to allocate memory"); - } + if (ctx->idat == NULL) + ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", + image->filename); memcpy(ctx->idat, atomDb.data, ctx->idatSize); } @@ -689,15 +692,12 @@ static MagickBooleanType ParseAtom(Image *image, DataBuffer *db, break; } - if (status != MagickTrue) - ThrowAndReturn("atom parsing failed"); - return status; } -static MagickSizeType ParseRootAtom(Image *image, MagickSizeType size, - HEICImageContext *ctx, ExceptionInfo *exception) +static MagickBooleanType ParseRootAtom(Image *image,MagickSizeType *size, + HEICImageContext *ctx,ExceptionInfo *exception) { MagickBooleanType status; @@ -708,11 +708,8 @@ static MagickSizeType ParseRootAtom(Image *image, MagickSizeType size, unsigned int atom; - if (size < 8) - { - ThrowFileException(exception, CorruptImageError, "Bad image: atom is too short", __func__); - return -1; - } + if (*size < 8) + ThrowAndReturn("atom is too short"); atom_size = ReadBlobMSBLong(image); atom = ReadBlobMSBLong(image); @@ -723,11 +720,8 @@ static MagickSizeType ParseRootAtom(Image *image, MagickSizeType size, } - if (atom_size > size) - { - ThrowFileException(exception, CorruptImageError, "Bad image: atom is too short", __func__); - return -1; - } + if (atom_size > *size) + ThrowAndReturn("atom is too short"); status = MagickTrue; @@ -747,16 +741,14 @@ static MagickSizeType ParseRootAtom(Image *image, MagickSizeType size, db.pos = 0; db.size = atom_size - 8; db.data = (unsigned char *) AcquireMagickMemory(db.size); - if (db.data == NULL) { - ThrowFileException(exception, CorruptImageError, "unable to allocate memory", __func__); - return -1; - } + if (db.data == NULL) + ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", + image->filename); count = ReadBlob(image, db.size, db.data); if (count != db.size) { RelinquishMagickMemory((void *)db.data); - ThrowFileException(exception, CorruptImageError, "Bad image: unable to read data", __func__); - return -1; + ThrowAndReturn("unable to read data"); } /* @@ -775,12 +767,8 @@ static MagickSizeType ParseRootAtom(Image *image, MagickSizeType size, break; } - if (status != MagickTrue) { - ThrowFileException(exception, CorruptImageError, "Bad image: atom parsing failed", __func__); - return -1; - } - - return size - atom_size; + *size=*size-atom_size; + return(MagickTrue); } static MagickBooleanType decodeGrid(HEICImageContext *ctx, ExceptionInfo *exception) @@ -852,7 +840,7 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un assoc = ctx->itemInfo[id].assocs[i] & 0x7f; if (assoc > ctx->itemPropsCount) { - ThrowFileException(exception, CorruptImageError,"Bad image: incorrect item property index", "decodeH265Image"); + ThrowImproperImageHeader("incorrect item property index"); goto err_out_free; } @@ -860,7 +848,7 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un case ATOM('h', 'v', 'c', 'C'): err = de265_push_data(ctx->h265Ctx, ctx->itemProps[assoc].data, ctx->itemProps[assoc].size, pos, (void*)2); if (err != DE265_OK) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to push data", "decodeH265Image"); + ThrowImproperImageHeader("unable to push data"); goto err_out_free; } @@ -884,14 +872,15 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un buffer = (unsigned char *) AcquireMagickMemory(ctx->itemInfo[id].size); if (buffer == NULL) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to allocate memory", "decodeH265Image"); - return MagickFalse; + (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, + "MemoryAllocationFailed","`%s'",image->filename); + goto err_out_free; } SeekBlob(image, ctx->itemInfo[id].offset, SEEK_SET); count = ReadBlob(image, ctx->itemInfo[id].size, buffer); if (count != ctx->itemInfo[id].size) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to read data", "decodeH265Image"); + ThrowImproperImageHeader("unable to read data"); goto err_out_free; } @@ -909,13 +898,13 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un err = de265_push_data(ctx->h265Ctx, buffer, ctx->itemInfo[id].size, pos, (void*)2); if (err != DE265_OK) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to push data", "decodeH265Image"); + ThrowImproperImageHeader("unable to push data"); goto err_out_free; } err = de265_flush_data(ctx->h265Ctx); if (err != DE265_OK) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to push data", "decodeH265Image"); + ThrowImproperImageHeader("unable to flush data"); goto err_out_free; } @@ -924,7 +913,7 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un do { err = de265_decode(ctx->h265Ctx, &more); if (err != DE265_OK) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to decode data", "decodeH265Image"); + ThrowImproperImageHeader("unable to decode data"); goto err_out_free; } @@ -934,7 +923,8 @@ static MagickBooleanType decodeH265Image(Image *image, HEICImageContext *ctx, un break; } - ThrowMagickException(exception, GetMagickModule(), CoderWarning, "Warning: decoding image: ", "%s", de265_get_error_text(warning)); + ThrowBinaryException(CoderWarning,(const char *)NULL, + de265_get_error_text(warning)); } const struct de265_image* img = de265_get_next_picture(ctx->h265Ctx); @@ -1043,7 +1033,6 @@ err_loop_free: err_out_free: de265_reset(ctx->h265Ctx); buffer = (unsigned char *) RelinquishMagickMemory(buffer); - ThrowFileException(exception, CorruptImageError,"Bad image: error decoding h265", __func__); return MagickFalse; } @@ -1123,31 +1112,24 @@ static Image *ReadHEICImage(const ImageInfo *image_info, count = MAX_ATOMS_IN_BOX; while (length && ctx.finished == MagickFalse && count--) { - length = ParseRootAtom(image, length, &ctx, exception); - if (length == (MagickSizeType)-1) { - ThrowFileException(exception,CorruptImageError,"Unable To Decode Image File","ReadHEIC"); + if (ParseRootAtom(image, &length, &ctx, exception) == MagickFalse) goto cleanup; - } } - if (ctx.finished != MagickTrue) { - ThrowFileException(exception,CorruptImageError,"Unable To Decode Image File","ReadHEIC"); + if (ctx.finished != MagickTrue) goto cleanup; - } /* Initialize h265 decoder */ ctx.h265Ctx = de265_new_decoder(); if (ctx.h265Ctx == NULL) { - ThrowFileException(exception,CorruptImageError,"Unable To Initialize Decoder","ReadHEIC"); + ThrowImproperImageHeader("unable to initialize decode"); goto cleanup; } - if (decodeGrid(&ctx, exception) != MagickTrue) { - ThrowFileException(exception,CorruptImageError,"Unable to decode image grid","ReadHEIC"); + if (decodeGrid(&ctx, exception) != MagickTrue) goto cleanup; - } count = (ctx.grid.rowsMinusOne + 1) * (ctx.grid.columnsMinusOne + 1); @@ -1157,7 +1139,8 @@ static Image *ReadHEICImage(const ImageInfo *image_info, ctx.tmp = CloneImage(image, 256, 256, MagickTrue, exception); if (ctx.tmp == NULL) { - ThrowFileException(exception,CorruptImageError,"Unable to clone image","ReadHEIC"); + (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, + "MemoryAllocationFailed","`%s'",image->filename); goto cleanup; } @@ -1177,14 +1160,15 @@ static Image *ReadHEICImage(const ImageInfo *image_info, assoc = ctx.itemInfo[ctx.grid.id].assocs[i] & 0x7f; if (assoc > ctx.itemPropsCount) { - ThrowFileException(exception,CorruptImageError,"Bad image: incorrect item property index","ReadHEIC"); + ThrowImproperImageHeader("incorrect item property index"); goto cleanup; } switch (ctx.itemProps[assoc].type) { case ATOM('i', 's', 'p', 'e'): if (ctx.itemProps[assoc].size < 12) { - ThrowReaderException(CorruptImageError,"Bad image: ispe atom is too short"); + ThrowImproperImageHeader("ispe atom is too short"); + goto cleanup; } crop_info.width = readInt(ctx.itemProps[assoc].data+4); crop_info.height = readInt(ctx.itemProps[assoc].data+8); @@ -1195,7 +1179,8 @@ static Image *ReadHEICImage(const ImageInfo *image_info, const char *value; if (ctx.itemProps[assoc].size < 1) { - ThrowReaderException(CorruptImageError,"Bad image: ispe atom is too short"); + ThrowImproperImageHeader("irot atom is too short"); + goto cleanup; } switch (ctx.itemProps[assoc].data[0]) @@ -1241,7 +1226,8 @@ static Image *ReadHEICImage(const ImageInfo *image_info, buffer = (unsigned char *) AcquireMagickMemory(info->size); if (buffer == NULL) { - ThrowFileException(exception, CorruptImageError,"Bad image: unable to allocate memory", "ReadHEIC"); + (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, + "MemoryAllocationFailed","`%s'",image->filename); goto cleanup; } -- 2.40.0