summaryrefslogtreecommitdiff
path: root/contrib/pngminus/png2pnm.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pngminus/png2pnm.c')
-rw-r--r--contrib/pngminus/png2pnm.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/contrib/pngminus/png2pnm.c b/contrib/pngminus/png2pnm.c
index ac295aafa..39a9f4673 100644
--- a/contrib/pngminus/png2pnm.c
+++ b/contrib/pngminus/png2pnm.c
@@ -1,8 +1,11 @@
/*
* png2pnm.c --- conversion from PNG-file to PGM/PPM-file
- * copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
+ * copyright (C) 1999,2017 by Willem van Schaik <willem at schaik.com>
*
* version 1.0 - 1999.10.15 - First version.
+ * 1.1 - 2017.04.22 - Add buffer-size check (Glenn Randers-Pehrson)
+ * 1.2 - 2017.08.24 - Fix potential overflow in buffer-size check
+ (Glenn Randers-Pehrson)
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
@@ -18,6 +21,7 @@
#include <mem.h>
#include <fcntl.h>
#endif
+#include <zlib.h>
#ifndef BOOL
#define BOOL unsigned char
@@ -51,7 +55,8 @@
int main (int argc, char *argv[]);
void usage ();
-BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha);
+BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw,
+ BOOL alpha);
/*
* main
@@ -84,7 +89,8 @@ int main(int argc, char *argv[])
if ((fp_al = fopen (argv[argi], "wb")) == NULL)
{
fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: can not create alpha-channel file %s\n", argv[argi]);
+ fprintf (stderr, "Error: can not create alpha-channel file %s\n",
+ argv[argi]);
exit (1);
}
break;
@@ -144,7 +150,7 @@ int main(int argc, char *argv[])
if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
{
fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: unsuccessful convertion of PNG-image\n");
+ fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
exit(1);
}
@@ -175,9 +181,11 @@ void usage()
fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n");
fprintf (stderr, " or: ... | png2pnm [options]\n");
fprintf (stderr, "Options:\n");
- fprintf (stderr, " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
+ fprintf (stderr,
+ " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
- fprintf (stderr, " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
+ fprintf (stderr,
+ " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
fprintf (stderr, " -h | -? print this help-information\n");
}
@@ -185,10 +193,11 @@ void usage()
* png2pnm
*/
-BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha)
+BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
+ volatile BOOL raw, BOOL alpha)
{
png_struct *png_ptr = NULL;
- png_info *info_ptr = NULL;
+ png_info *info_ptr = NULL;
png_byte buf[8];
png_byte *png_pixels = NULL;
png_byte **row_pointers = NULL;
@@ -211,13 +220,13 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
if (ret != 8)
return FALSE;
- ret = !png_sig_cmp (buf, 0, 8);
- if (!ret)
+ ret = png_sig_cmp (buf, 0, 8);
+ if (ret)
return FALSE;
/* create png and info structures */
- png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
+ png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
NULL, NULL, NULL);
if (!png_ptr)
return FALSE; /* out of memory */
@@ -260,7 +269,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
png_set_expand (png_ptr);
#ifdef NJET
- /* downgrade 16-bit images to 8 bit */
+ /* downgrade 16-bit images to 8-bit */
if (bit_depth == 16)
png_set_strip_16 (png_ptr);
/* transform grayscale images into full-color */
@@ -314,12 +323,21 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
/* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = png_get_rowbytes (png_ptr, info_ptr);
- if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
+ if ((row_bytes == 0 || (size_t)height > ((size_t)(-1))/(size_t)row_bytes))
+ {
+ /* too big */
+ png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+ return FALSE;
+ }
+ if ((png_pixels = (png_byte *)
+ malloc ((size_t)row_bytes * (size_t)height * sizeof (png_byte))) == NULL)
+ {
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
return FALSE;
}
- if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
+ if ((row_pointers = (png_byte **)
+ malloc ((size_t)height * sizeof (png_bytep))) == NULL)
{
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
free (png_pixels);
@@ -328,7 +346,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
}
/* 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;
/* now we can go ahead and just read the whole image */
@@ -371,9 +389,9 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
/* write data to PNM file */
pix_ptr = png_pixels;
- for (row = 0; row < height; row++)
+ for (row = 0; row < (int) height; row++)
{
- for (col = 0; col < width; col++)
+ for (col = 0; col < (int) width; col++)
{
for (i = 0; i < (channels - alpha_present); i++)
{
@@ -381,7 +399,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
fputc ((int) *pix_ptr++ , pnm_file);
else
if (bit_depth == 16){
- dep_16 = (long) *pix_ptr++;
+ dep_16 = (long) *pix_ptr++;
fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
}
else
@@ -400,10 +418,11 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
if (raw)
fputc ((int) *pix_ptr++ , alpha_file);
else
- if (bit_depth == 16){
- dep_16 = (long) *pix_ptr++;
+ if (bit_depth == 16)
+ {
+ dep_16 = (long) *pix_ptr++;
fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
- }
+ }
else
fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
}
@@ -424,6 +443,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL a
if (png_pixels != (unsigned char*) NULL)
free (png_pixels);
+ PNG_UNUSED(raw) /* to quiet a Coverity defect */
return TRUE;
} /* end of source */