]> granicus.if.org Git - imagemagick/commitdiff
Several changes to exception throwing and fixed several memory leaks.
authorDirk Lemstra <dirk@git.imagemagick.org>
Thu, 8 Feb 2018 22:12:26 +0000 (23:12 +0100)
committerDirk Lemstra <dirk@git.imagemagick.org>
Thu, 8 Feb 2018 22:12:26 +0000 (23:12 +0100)
coders/heic.c

index 4753fdbb4707467fcecdad15ef4265c27c6a62b5..0e0cd2d09455d1c08d1726b170550ebfa5dcbcba 100644 (file)
@@ -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;
 }
 \f
@@ -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;
     }