File GraphicsMagick-CVE-2026-30883.patch of Package GraphicsMagick.43212
Index: GraphicsMagick-1.3.42/coders/png.c
===================================================================
--- GraphicsMagick-1.3.42.orig/coders/png.c
+++ GraphicsMagick-1.3.42/coders/png.c
@@ -7057,15 +7057,15 @@ ModuleExport void UnregisterPNGImage(voi
*/
-static void
+static MagickPassFail
png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
png_info *ping_info, const char *profile_type,
const char *profile_description,
const unsigned char *profile_data,
- png_uint_32 length)
+ size_t length,ExceptionInfo *exception)
{
png_textp
- text;
+ text = (png_textp) NULL;
register long
i;
@@ -7076,34 +7076,61 @@ png_write_raw_profile(const ImageInfo *i
png_charp
dp;
- png_uint_32
+ size_t
allocated_length,
description_length;
- unsigned char
+ unsigned int
+ status = MagickPass;
+
+ static const unsigned char
hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
if (image_info->verbose)
{
- (void) printf("writing raw profile: type=%.1024s, length=%lu\n",
- profile_type, (unsigned long)length);
+ (void) printf("writing raw profile: type=%.1024s, length=%zu\n",
+ profile_type, length);
+ }
+ if (length >= (PNG_UINT_31_MAX / 2))
+ {
+ ThrowException(exception,ResourceLimitError,UnableToAddOrRemoveProfile,image_info->filename);
+ status=MagickFail;
+ return status;
+ }
+ description_length=strlen((const char *) profile_description);
+ allocated_length=(length*2 + (length >> 5) + 20 + description_length);
+ if (((png_uint_32)allocated_length) < length)
+ {
+ ThrowException(exception,CoderError,ArithmeticOverflow,image_info->filename);
+ status=MagickFail;
+ return status;
}
#if PNG_LIBPNG_VER >= 14000
text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
#else
text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
#endif
- description_length=(png_uint_32) strlen((const char *) profile_description);
- allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
- + description_length);
+ if (text == (png_textp) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image_info->filename);
+ status=MagickFail;
+ return status;
+ }
+ (void) memset(&text[0],0,sizeof(png_text));
+
#if PNG_LIBPNG_VER >= 14000
- text[0].text=(png_charp) png_malloc(ping,
- (png_alloc_size_t) allocated_length);
- text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
+ text[0].text=(png_charp) png_malloc(ping,(png_alloc_size_t) allocated_length);
+ text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
#else
- text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
- text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
+ text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
+ text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
#endif
+ if ((text[0].text == (png_charp) NULL) || (text[0].key == (png_charp) NULL))
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image_info->filename);
+ status=MagickFail;
+ goto png_write_raw_profile_cleanup;
+ }
text[0].key[0]='\0';
(void) strlcat(text[0].key, "Raw profile type ", 80);
(void) strncat(text[0].key, (const char *) profile_type, 61);
@@ -7113,7 +7140,7 @@ png_write_raw_profile(const ImageInfo *i
(void) strlcpy(dp,(const char *) profile_description,(allocated_length-(dp-text[0].text)));
dp+=strlen(dp);
*dp++='\n';
- (void) snprintf(dp,(allocated_length-(dp-text[0].text)),"%8lu ",(unsigned long)length);
+ (void) snprintf(dp,(allocated_length-(dp-text[0].text)),"%8zu ",length);
dp+=strlen(dp);
for (i=0; i < (long) length; i++)
{
@@ -7125,14 +7152,21 @@ png_write_raw_profile(const ImageInfo *i
*dp++='\n';
*dp='\0';
text[0].text_length=dp-text[0].text;
+ if (text[0].text_length > allocated_length)
+ {
+ ThrowException(exception,CoderError,ArithmeticOverflow,image_info->filename);
+ status=MagickFail;
+ goto png_write_raw_profile_cleanup;
+ }
text[0].compression=image_info->compression == NoCompression ||
(image_info->compression == UndefinedCompression &&
text[0].text_length < 128) ? -1 : 0;
- if (text[0].text_length <= allocated_length)
- png_set_text(ping,ping_info,text,1);
+ png_set_text(ping,ping_info,text,1); /* returns void */
+ png_write_raw_profile_cleanup:
png_free(ping,text[0].text);
png_free(ping,text[0].key);
png_free(ping,text);
+ return status;
}
static MagickPassFail WriteOnePNGImage(MngInfo *mng_info,
@@ -8304,11 +8338,12 @@ static MagickPassFail WriteOnePNGImage(M
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Setting up text chunk with"
" iCCP Profile");
- png_write_raw_profile(image_info,ping,ping_info,
- "icm",
- "ICC Profile",
- profile_info,
- (png_uint_32) profile_length);
+ (void) png_write_raw_profile(image_info,ping,ping_info,
+ "icm",
+ "ICC Profile",
+ profile_info,
+ (png_uint_32) profile_length,
+ &image->exception);
}
#endif
}
@@ -8318,11 +8353,12 @@ static MagickPassFail WriteOnePNGImage(M
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Setting up text chunk with"
" iPTC Profile");
- png_write_raw_profile(image_info,ping,ping_info,
- "iptc",
- "IPTC profile",
- profile_info,
- (png_uint_32) profile_length);
+ (void) png_write_raw_profile(image_info,ping,ping_info,
+ "iptc",
+ "IPTC profile",
+ profile_info,
+ (png_uint_32) profile_length,
+ &image->exception);
}
else if (LocaleCompare(profile_name,"exif") == 0)
/* Do not write exif; we'll write it later as eXIf */
@@ -8334,11 +8370,12 @@ static MagickPassFail WriteOnePNGImage(M
" Setting up text chunk with"
" %s profile",
profile_name);
- png_write_raw_profile(image_info,ping,ping_info,
- profile_name,
- "generic profile",
- profile_info,
- (png_uint_32) profile_length);
+ (void) png_write_raw_profile(image_info,ping,ping_info,
+ profile_name,
+ "generic profile",
+ profile_info,
+ (png_uint_32) profile_length,
+ &image->exception);
}
}