[libpng16] Stop memory leak when returning from png_handle_eXIf() with an error

(Bug report from the OSS-fuzz project).
This commit is contained in:
Glenn Randers-Pehrson 2017-08-01 21:42:16 -05:00
parent cb628b2e4e
commit 71a56180e5
6 changed files with 50 additions and 21 deletions

View File

@ -1,4 +1,4 @@
Libpng 1.6.32beta03 - August 1, 2017
Libpng 1.6.32beta03 - August 2, 2017
This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version.
@ -39,9 +39,10 @@ Version 1.6.32beta01 [July 31, 2017]
Version 1.6.32beta02 [August 1, 2017]
Updated contrib/libtests/pngunknown.c with eXIf chunk.
Version 1.6.32beta03 [August 1, 2017]
Version 1.6.32beta03 [August 2, 2017]
Initialized btoa[] in pngstest.c
Stop memory leak when returning from png_handle_eXIf() with an error.
Stop memory leak when returning from png_handle_eXIf() with an error
(Bug report from the OSS-fuzz project).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -5919,12 +5919,13 @@ Version 1.6.32beta01 [July 31, 2017]
png_set_eXIf_1(), respectively, to avoid breaking API compatibility
with libpng-1.6.31.
Version 1.6.32beta02 [August 1, 2017]
Version 1.6.32beta02 [August 2, 2017]
Updated contrib/libtests/pngunknown.c with eXIf chunk.
Version 1.6.32beta03 [August 1, 2017]
Version 1.6.32beta03 [August 2, 2017]
Initialized btoa[] in pngstest.c
Stop memory leak when returning from png_handle_eXIf() with an error.
Stop memory leak when returning from png_handle_eXIf() with an error
(Bug report from the OSS-fuzz project).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -186,8 +186,11 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
#endif
#ifdef PNG_eXIf_SUPPORTED
int num_exif;
int num_exif; /* Added at libpng-1.6.31 */
png_bytep exif;
# ifdef PNG_READ_eXIf_SUPPORTED
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
# endif
#endif
#ifdef PNG_hIST_SUPPORTED

View File

@ -2014,6 +2014,7 @@ void /* PRIVATE */
png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
unsigned int i;
png_bytep eXIf_buf;
png_debug(1, "in png_handle_eXIf");
@ -2031,18 +2032,25 @@ png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
eXIf_buf = png_voidcast(png_bytep,
png_malloc_warn(png_ptr, length));
if (eXIf_buf == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
return;
}
info_ptr->eXIf_buf = eXIf_buf; /* So it will be freed on error */
info_ptr->free_me |= PNG_FREE_EXIF;
for (i = 0; i < length; i++)
{
png_byte buf[1];
png_crc_read(png_ptr, buf, 1);
eXIf_buf[i] = buf[0];
}
info_ptr->eXIf_buf = NULL;
if (png_crc_finish(png_ptr, 0) != 0)
{
png_free(png_ptr, eXIf_buf);
return;
}
png_set_eXIf_1(png_ptr, info_ptr, length, eXIf_buf);

View File

@ -146,7 +146,11 @@ png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL)
return;
png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0);
if (info_ptr->exif)
{
png_free(png_ptr, info_ptr->exif);
info_ptr->exif = NULL;
}
info_ptr->num_exif = num_exif;

View File

@ -936,8 +936,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
png_free(read_ptr, row_buf);
row_buf = NULL;
if (verbose != 0)
fprintf(STDERR, " destroy read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
if (verbose != 0)
fprintf(STDERR, " destroy write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
@ -952,11 +956,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
if (setjmp(png_jmpbuf(write_ptr)))
{
fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
if (verbose != 0)
fprintf(STDERR, " destroying read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
if (verbose != 0)
fprintf(STDERR, " destroying write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
FCLOSE(fpin);
FCLOSE(fpout);
return (1);
@ -1192,16 +1198,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
}
}
#endif
#ifdef PNG_eXIf_SUPPORTED
#ifdef PNG_READ_eXIf_SUPPORTED
{
png_bytep exif;
png_bytep exif=NULL;
png_uint_32 exif_length;
if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
{
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
if (exif_length > 1)
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
# ifdef PNG_WRITE_eXIf_SUPPORTED
png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
# endif
}
}
#endif
@ -1547,16 +1556,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
}
}
#endif
#ifdef PNG_eXIf_SUPPORTED
#ifdef PNG_READ_eXIf_SUPPORTED
{
png_bytep exif;
png_bytep exif=NULL;
png_uint_32 exif_length;
if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
{
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
if (exif_length > 1)
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
# ifdef PNG_WRITE_eXIf_SUPPORTED
png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
# endif
}
}
#endif