[libpng15] Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c

and fixed uninitialized variable in contrib/gregbook/rpng2-x.c
This commit is contained in:
Glenn Randers-Pehrson 2015-07-30 11:32:56 -05:00
parent aa24431c93
commit bb98fdbf31
4 changed files with 93 additions and 39 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.5.24beta01 - July 24, 2015 Libpng 1.5.24beta01 - July 30, 2015
This is not intended to be a public release. It will be replaced 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. within a few weeks by a public version or by another test version.
@ -27,7 +27,12 @@ Other information:
Changes since the last public release (1.5.23): Changes since the last public release (1.5.23):
Version 1.5.24beta01 [July 24, 2015] Version 1.5.24beta01 [July 30, 2015]
Avoid potentially dereferencing NULL info_ptr in png_info_init_3().
Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and
PNG_WEIGHT_FACTOR macros.
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -4373,7 +4373,12 @@ Version 1.5.23rc03 [July 15, 2015]
Version 1.5.23 [July 23, 2015] Version 1.5.23 [July 23, 2015]
No changes. No changes.
Version 1.5.24beta01 [July 24, 2015] Version 1.5.24beta01 [July 30, 2015]
Avoid potentially dereferencing NULL info_ptr in png_info_init_3().
Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and
PNG_WEIGHT_FACTOR macros.
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -41,10 +41,12 @@
unexpected-EOF and file-read-error cases; fixed Trace() cut-and- unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
paste bugs paste bugs
- 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
- 2.04: Added "void(foo);" statements to quiet pedantic compiler warnings
about unused variables (GR-P)
- 2.05: Use nanosleep() instead of usleep(), which is deprecated (GR-P).
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. Copyright (c) 1998-2010, 2014-2015 Greg Roelofs. All rights reserved.
This software is provided "as is," without warranty of any kind, This software is provided "as is," without warranty of any kind,
express or implied. In no event shall the author or contributors express or implied. In no event shall the author or contributors
@ -95,7 +97,7 @@
#define PROGNAME "rpng2-x" #define PROGNAME "rpng2-x"
#define LONGNAME "Progressive PNG Viewer for X" #define LONGNAME "Progressive PNG Viewer for X"
#define VERSION "2.03 of 25 February 2010" #define VERSION "2.04 of 15 June 2014"
#define RESNAME "rpng2" /* our X resource application name */ #define RESNAME "rpng2" /* our X resource application name */
#define RESCLASS "Rpng" /* our X resource class name */ #define RESCLASS "Rpng" /* our X resource class name */
@ -111,6 +113,19 @@
#include <X11/Xos.h> #include <X11/Xos.h>
#include <X11/keysym.h> /* defines XK_* macros */ #include <X11/keysym.h> /* defines XK_* macros */
#if _POSIX_C_SOURCE >= 199309L /* have nanosleep() */
# undef usleep
# define usleep(usec) { \
struct timespec ts; \
ts.tv_sec = 0; \
ts.tv_nsec = (usec) * 1000; \
nanosleep(&ts, NULL); }
# endif
#ifndef usleep /* have neither nanosleep() nor usleep() */
# define usleep(x) sleep(((x)+499999)/1000000)
#endif
#ifdef VMS #ifdef VMS
# include <unistd.h> # include <unistd.h>
#endif #endif
@ -456,40 +471,47 @@ int main(int argc, char **argv)
fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
readpng2_version_info(); readpng2_version_info();
fprintf(stderr, "\n" fprintf(stderr, "\n"
"Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n" "Usage: ");
fprintf(stderr,
"%s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
" %*s [-usleep dur | -timing] [-pause]\n",
PROGNAME, (int)strlen(PROGNAME), " ");
fprintf(stderr,
#ifdef FEATURE_LOOP #ifdef FEATURE_LOOP
" %*s [-usleep dur | -timing] [-pause] [-loop [sec]] file.png\n\n" " [-loop [sec]]"
#else
" %*s [-usleep dur | -timing] [-pause] file.png\n\n"
#endif #endif
" file.png\n\n");
fprintf(stderr,
" xdpy\tname of the target X display (e.g., ``hostname:0'')\n" " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
" exp \ttransfer-function exponent (``gamma'') of the display\n" " exp \ttransfer-function exponent (``gamma'') of the display\n"
"\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
"\t\t to the product of the lookup-table exponent (varies)\n" "\t\t to the product of the lookup-table exponent (varies)\n",
default_display_exponent);
fprintf(stderr,
"\t\t and the CRT exponent (usually 2.2); must be positive\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n"
" bg \tdesired background color in 7-character hex RGB format\n" " bg \tdesired background color in 7-character hex RGB format\n"
"\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
"\t\t used with transparent images; overrides -bgpat\n" "\t\t used with transparent images; overrides -bgpat\n"
" pat \tdesired background pattern number (0-%d); used with\n" " pat \tdesired background pattern number (0-%d); used with\n"
"\t\t transparent images; overrides -bgcolor\n" "\t\t transparent images; overrides -bgcolor\n",
num_bgpat-1);
#ifdef FEATURE_LOOP #ifdef FEATURE_LOOP
fprintf(stderr,
" -loop\tloops through background images after initial display\n" " -loop\tloops through background images after initial display\n"
"\t\t is complete (depends on -bgpat)\n" "\t\t is complete (depends on -bgpat)\n"
" sec \tseconds to display each background image (default = 2)\n" " sec \tseconds to display each background image (default = 2)\n");
#endif #endif
fprintf(stderr,
" dur \tduration in microseconds to wait after displaying each\n" " dur \tduration in microseconds to wait after displaying each\n"
"\t\t row (for demo purposes)\n" "\t\t row (for demo purposes)\n"
" -timing\tenables delay for every block read, to simulate modem\n" " -timing\tenables delay for every block read, to simulate modem\n"
"\t\t download of image (~36 Kbps)\n" "\t\t download of image (~36 Kbps)\n"
" -pause\tpauses after displaying each pass until mouse clicked\n" " -pause\tpauses after displaying each pass until mouse clicked\n"
"\nPress Q, Esc or mouse button 1 (within image window, after image\n" "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
"is displayed) to quit.\n" "is displayed) to quit.\n");
"\n", PROGNAME,
(int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1);
exit(1); exit(1);
} }
if (!(infile = fopen(filename, "rb"))) { if (!(infile = fopen(filename, "rb"))) {
fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
++error; ++error;
@ -735,6 +757,8 @@ int main(int argc, char **argv)
Trace((stderr, "about to call rpng2_x_cleanup()\n")) Trace((stderr, "about to call rpng2_x_cleanup()\n"))
rpng2_x_cleanup(); rpng2_x_cleanup();
(void)argc; /* Unused */
return 0; return 0;
} }
@ -1826,6 +1850,9 @@ static void rpng2_x_redisplay_image(ulg startcol, ulg startrow,
XFlush(display); XFlush(display);
} }
(void)startcol;
(void)width;
} /* end function rpng2_x_redisplay_image() */ } /* end function rpng2_x_redisplay_image() */

View File

@ -3,6 +3,7 @@
* copyright (C) 1999 by Willem van Schaik <willem@schaik.com> * copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
* *
* version 1.0 - 1999.10.15 - First version. * version 1.0 - 1999.10.15 - First version.
* version 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
* *
* Permission to use, copy, modify, and distribute this software and * Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted, * its documentation for any purpose and without fee is hereby granted,
@ -50,7 +51,8 @@
int main (int argc, char *argv[]); int main (int argc, char *argv[]);
void usage (); void usage ();
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
BOOL alpha);
void get_token(FILE *pnm_file, char *token); void get_token(FILE *pnm_file, char *token);
png_uint_32 get_data (FILE *pnm_file, int depth); png_uint_32 get_data (FILE *pnm_file, int depth);
png_uint_32 get_value (FILE *pnm_file, int depth); png_uint_32 get_value (FILE *pnm_file, int depth);
@ -176,7 +178,8 @@ void usage()
fprintf (stderr, " or: ... | pnm2png [options]\n"); fprintf (stderr, " or: ... | pnm2png [options]\n");
fprintf (stderr, "Options:\n"); fprintf (stderr, "Options:\n");
fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n"); fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n");
fprintf (stderr, " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n"); fprintf (stderr,
" -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
fprintf (stderr, " -h | -? print this help-information\n"); fprintf (stderr, " -h | -? print this help-information\n");
} }
@ -184,30 +187,31 @@ void usage()
* pnm2png * pnm2png
*/ */
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
BOOL alpha)
{ {
png_struct *png_ptr = NULL; png_struct *png_ptr = NULL;
png_info *info_ptr = NULL; png_info *info_ptr = NULL;
png_byte *png_pixels = NULL; png_byte *png_pixels = NULL;
png_byte **row_pointers = NULL; png_byte **row_pointers = NULL;
png_byte *pix_ptr = NULL; png_byte *pix_ptr = NULL;
png_uint_32 row_bytes; volatile png_uint_32 row_bytes;
char type_token[16]; char type_token[16];
char width_token[16]; char width_token[16];
char height_token[16]; char height_token[16];
char maxval_token[16]; char maxval_token[16];
int color_type; volatile int color_type=1;
unsigned long ul_width=0, ul_alpha_width=0; unsigned long ul_width=0, ul_alpha_width=0;
unsigned long ul_height=0, ul_alpha_height=0; unsigned long ul_height=0, ul_alpha_height=0;
unsigned long ul_maxval=0; unsigned long ul_maxval=0;
png_uint_32 width, alpha_width; volatile png_uint_32 width=0, height=0;
png_uint_32 height, alpha_height; volatile png_uint_32 alpha_width=0, alpha_height=0;
png_uint_32 maxval; png_uint_32 maxval;
int bit_depth = 0; volatile int bit_depth = 0;
int channels; int channels=0;
int alpha_depth = 0; int alpha_depth = 0;
int alpha_present; int alpha_present=0;
int row, col; int row, col;
BOOL raw, alpha_raw = FALSE; BOOL raw, alpha_raw = FALSE;
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
@ -353,8 +357,10 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
channels = 3; channels = 3;
else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
channels = 4; channels = 4;
#if 0
else else
channels = 0; /* should not happen */ channels = 0; /* cannot happen */
#endif
alpha_present = (channels - 1) % 2; alpha_present = (channels - 1) % 2;
@ -367,23 +373,24 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
/* row_bytes is the width x number of channels x (bit-depth / 8) */ /* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) if ((png_pixels = (png_byte *)
malloc (row_bytes * height * sizeof (png_byte))) == NULL)
return FALSE; return FALSE;
/* read data from PNM file */ /* read data from PNM file */
pix_ptr = png_pixels; pix_ptr = png_pixels;
for (row = 0; row < height; row++) for (row = 0; row < (int) height; row++)
{ {
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
if (packed_bitmap) { if (packed_bitmap) {
for (i = 0; i < row_bytes; i++) for (i = 0; i < (int) row_bytes; i++)
/* png supports this format natively so no conversion is needed */ /* png supports this format natively so no conversion is needed */
*pix_ptr++ = get_data (pnm_file, 8); *pix_ptr++ = get_data (pnm_file, 8);
} else } else
#endif #endif
{ {
for (col = 0; col < width; col++) for (col = 0; col < (int) width; col++)
{ {
for (i = 0; i < (channels - alpha_present); i++) for (i = 0; i < (channels - alpha_present); i++)
{ {
@ -421,15 +428,20 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
} /* end for row */ } /* end for row */
/* prepare the standard PNG structures */ /* prepare the standard PNG structures */
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_ptr = png_create_write_struct (png_get_libpng_ver(NULL), NULL, NULL,
NULL);
if (!png_ptr) if (!png_ptr)
{ {
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
info_ptr = png_create_info_struct (png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
@ -444,7 +456,9 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
/* setjmp() must be called in every function that calls a PNG-reading libpng function */ /* setjmp() must be called in every function that calls a PNG-reading libpng function */
if (setjmp (png_jmpbuf(png_ptr))) if (setjmp (png_jmpbuf(png_ptr)))
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
@ -462,25 +476,28 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
/* if needed we will allocate memory for an new array of row-pointers */ /* if needed we will allocate memory for an new array of row-pointers */
if (row_pointers == (unsigned char**) NULL) if (row_pointers == (unsigned char**) NULL)
{ {
if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) if ((row_pointers = (png_byte **)
malloc (height * sizeof (png_bytep))) == NULL)
{ {
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
free (png_pixels);
png_pixels = NULL;
return FALSE; return FALSE;
} }
} }
/* set the individual row_pointers to point at the correct offsets */ /* set the individual row_pointers to point at the correct offsets */
for (i = 0; i < (height); i++) for (i = 0; i < (int) height; i++)
row_pointers[i] = png_pixels + i * row_bytes; row_pointers[i] = png_pixels + i * row_bytes;
/* write out the entire image data in one call */ /* write out the entire image data in one call */
png_write_image (png_ptr, row_pointers); png_write_image (png_ptr, row_pointers);
/* write the additional chuncks to the PNG file (not really needed) */ /* write the additional chunks to the PNG file (not really needed) */
png_write_end (png_ptr, info_ptr); png_write_end (png_ptr, info_ptr);
/* clean up after the write, and free any memory allocated */ /* clean up after the write, and free any memory allocated */
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, &info_ptr);
if (row_pointers != (unsigned char**) NULL) if (row_pointers != (unsigned char**) NULL)
free (row_pointers); free (row_pointers);