[libpng15] Merged pngtest.c with libpng-1.6.17/pngtest.c

Display user limits in the output from pngtest.
Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column
  and 1-million-row default limits in pnglibconf.dfa, that can be reset
  by the user at build time or run time.  This provides a more robust
  defense against DOS and as-yet undiscovered overflows.
This commit is contained in:
Glenn Randers-Pehrson
2015-02-16 22:56:30 -06:00
parent c34f3658a7
commit 8a6253ed6f
7 changed files with 151 additions and 133 deletions

152
pngtest.c
View File

@@ -1,8 +1,7 @@
/* pngtest.c - a simple test program to test libpng
*
* Last changed in libpng 1.5.19 [August 21, 2014]
* Copyright (c) 1998-2014 Glenn Randers-Pehrson
* Last changed in libpng 1.5.22 [(PENDING RELEASE)]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@@ -283,7 +282,8 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
png_uint_32 n, nstop;
int channel;
int color_channels = row_info->channels;
if (row_info->color_type > 3)color_channels--;
if (row_info->color_type > 3)
color_channels--;
for (n = 0, nstop=row_info->width; n<nstop; n++)
{
@@ -310,7 +310,7 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
}
}
}
#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
#endif /* WRITE_USER_TRANSFORM */
#ifndef PNG_STDIO_SUPPORTED
/* START of code to validate stdio-free compilation */
@@ -419,7 +419,7 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
#endif
}
#endif /* !PNG_STDIO_SUPPORTED */
#endif /* !STDIO */
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
@@ -588,7 +588,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
if (pinfo->next == NULL)
{
fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
fprintf(STDERR, "Pointer %p not found\n", ptr);
break;
}
@@ -604,7 +604,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
free(ptr);
ptr = NULL;
}
#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
#endif /* USER_MEM && DEBUG */
/* END of code to test memory allocation/deallocation */
@@ -643,7 +643,7 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
{
int location;
if ((data->location[0] & what) || (data->location[1] & what))
if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0)
return 0; /* already have one of these */
/* Find where we are (the code below zeroes info_ptr to indicate that the
@@ -652,7 +652,7 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
if (data->info_ptr == NULL) /* after IDAT */
location = what | after_IDAT;
else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE))
else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0)
location = what | before_IDAT;
else
@@ -667,8 +667,8 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
return 1; /* handled */
}
static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
png_unknown_chunkp chunk)
static int PNGCBAPI
read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
{
struct user_chunk_data *my_user_chunk_data =
(struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
@@ -699,7 +699,7 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
if (chunk->data[0] != 0 && chunk->data[0] != 1)
return (-1); /* Invalid mode */
if (set_location(png_ptr, my_user_chunk_data, have_sTER))
if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
{
my_user_chunk_data->sTER_mode=chunk->data[0];
return (1);
@@ -718,7 +718,7 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
if (chunk->size != 9)
return (-1); /* Error return */
if (!set_location(png_ptr, my_user_chunk_data, have_vpAg))
if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
return (0); /* duplicate vpAg */
my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
@@ -779,8 +779,8 @@ write_chunks(png_structp write_ptr, int location)
write_vpAg_chunk(write_ptr);
}
}
#endif /* PNG_WRITE_SUPPORTED */
#else /* !PNG_READ_USER_CHUNKS_SUPPORTED */
#endif /* WRITE */
#else /* !READ_USER_CHUNKS */
# define write_chunks(pp,loc) ((void)0)
#endif
/* END of code to demonstrate user chunk support */
@@ -1049,7 +1049,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
int interlace_type, compression_type, filter_type;
if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
&color_type, &interlace_type, &compression_type, &filter_type))
&color_type, &interlace_type, &compression_type, &filter_type) != 0)
{
png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
color_type, interlace_type, compression_type, filter_type);
@@ -1082,7 +1082,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
blue_y;
if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
&red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y))
&red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
{
png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
red_y, green_x, green_y, blue_x, blue_y);
@@ -1093,7 +1093,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
png_fixed_point gamma;
if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
}
#endif
@@ -1105,7 +1105,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
blue_y;
if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
&red_y, &green_x, &green_y, &blue_x, &blue_y))
&red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
{
png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
red_y, green_x, green_y, blue_x, blue_y);
@@ -1116,7 +1116,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
double gamma;
if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
png_set_gAMA(write_ptr, write_info_ptr, gamma);
}
#endif
@@ -1130,7 +1130,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
int compression_type;
if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
&profile, &proflen))
&profile, &proflen) != 0)
{
png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
profile, proflen);
@@ -1141,7 +1141,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
int intent;
if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
png_set_sRGB(write_ptr, write_info_ptr, intent);
}
#endif
@@ -1149,14 +1149,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
png_colorp palette;
int num_palette;
if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
}
#ifdef PNG_bKGD_SUPPORTED
{
png_color_16p background;
if (png_get_bKGD(read_ptr, read_info_ptr, &background))
if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
{
png_set_bKGD(write_ptr, write_info_ptr, background);
}
@@ -1166,7 +1166,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
png_uint_16p hist;
if (png_get_hIST(read_ptr, read_info_ptr, &hist))
if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
png_set_hIST(write_ptr, write_info_ptr, hist);
}
#endif
@@ -1176,7 +1176,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
int unit_type;
if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
&unit_type))
&unit_type) != 0)
{
png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
}
@@ -1190,7 +1190,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
int type, nparams;
if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
&nparams, &units, &params))
&nparams, &units, &params) != 0)
{
png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
nparams, units, params);
@@ -1202,7 +1202,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
png_uint_32 res_x, res_y;
int unit_type;
if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
&unit_type) != 0)
png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
}
#endif
@@ -1210,7 +1211,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
png_color_8p sig_bit;
if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
}
#endif
@@ -1222,7 +1223,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
double scal_width, scal_height;
if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
&scal_height))
&scal_height) != 0)
{
png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
}
@@ -1234,7 +1235,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
png_charp scal_width, scal_height;
if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
&scal_height))
&scal_height) != 0)
{
png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
scal_height);
@@ -1274,7 +1275,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
png_timep mod_time;
if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)
{
png_set_tIME(write_ptr, write_info_ptr, mod_time);
#ifdef PNG_TIME_RFC1123_SUPPORTED
@@ -1283,12 +1284,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
* we use it.
*/
memcpy(tIME_string,
png_convert_to_rfc1123(read_ptr, mod_time),
png_sizeof(tIME_string));
png_convert_to_rfc1123(read_ptr, mod_time),
png_sizeof(tIME_string));
tIME_string[png_sizeof(tIME_string) - 1] = '\0';
tIME_chunk_present++;
#endif /* PNG_TIME_RFC1123_SUPPORTED */
#endif /* TIME_RFC1123 */
}
}
#endif
@@ -1299,7 +1300,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
png_color_16p trans_color;
if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
&trans_color))
&trans_color) != 0)
{
int sample_max = (1 << bit_depth);
/* libpng doesn't reject a tRNS chunk with out-of-range samples */
@@ -1382,11 +1383,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
#ifndef SINGLE_ROWBUF_ALLOC
pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
row_buf = (png_bytep)png_malloc(read_ptr,
png_get_rowbytes(read_ptr, read_info_ptr));
pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf,
png_get_rowbytes(read_ptr, read_info_ptr));
pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
(unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
#endif /* !SINGLE_ROWBUF_ALLOC */
png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
@@ -1403,7 +1405,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
t_encode += (t_stop - t_start);
t_start = t_stop;
#endif
#endif /* PNG_WRITE_SUPPORTED */
#endif /* WRITE */
#ifndef SINGLE_ROWBUF_ALLOC
pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
@@ -1456,7 +1458,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
png_timep mod_time;
if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
{
png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
#ifdef PNG_TIME_RFC1123_SUPPORTED
@@ -1464,12 +1466,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
pointed to by png_convert_to_rfc1123() gets free'ed before
we use it */
memcpy(tIME_string,
png_convert_to_rfc1123(read_ptr, mod_time),
png_sizeof(tIME_string));
png_convert_to_rfc1123(read_ptr, mod_time),
png_sizeof(tIME_string));
tIME_string[png_sizeof(tIME_string) - 1] = '\0';
tIME_chunk_present++;
#endif /* PNG_TIME_RFC1123_SUPPORTED */
#endif /* TIME_RFC1123 */
}
}
#endif
@@ -1674,7 +1676,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
}
}
}
#endif /* PNG_WRITE_SUPPORTED */
#endif /* WRITE */
FCLOSE(fpin);
FCLOSE(fpout);
@@ -1697,6 +1699,8 @@ main(int argc, char *argv[])
int multiple = 0;
int ierror = 0;
png_structp dummy_ptr;
fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
fprintf(STDERR, "%s", png_get_copyright(NULL));
@@ -1779,10 +1783,11 @@ main(int argc, char *argv[])
}
}
if (!multiple && argc == 3 + verbose)
if (multiple == 0 && argc == 3 + verbose)
outname = argv[2 + verbose];
if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
if ((multiple == 0 && argc > 3 + verbose) ||
(multiple != 0 && argc < 2))
{
fprintf(STDERR,
"usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
@@ -1804,6 +1809,9 @@ main(int argc, char *argv[])
{
int kerror;
fprintf(STDERR, "\n Testing %s:", argv[i]);
#if PNG_DEBUG > 0
fprintf(STDERR, "\n");
#endif
kerror = test_one_file(argv[i], outname);
if (kerror == 0)
{
@@ -1818,16 +1826,14 @@ main(int argc, char *argv[])
#endif
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
for (k = 0; k<256; k++)
if (filters_used[k])
if (filters_used[k] != 0)
fprintf(STDERR, " Filter %d was used %lu times\n",
k, (unsigned long)filters_used[k]);
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
if (tIME_chunk_present != 0)
fprintf(STDERR, " tIME = %s\n", tIME_string);
tIME_chunk_present = 0;
#endif /* PNG_TIME_RFC1123_SUPPORTED */
if (tIME_chunk_present != 0)
fprintf(STDERR, " tIME = %s\n", tIME_string);
#endif /* TIME_RFC1123 */
}
else
@@ -1849,9 +1855,9 @@ main(int argc, char *argv[])
while (pinfo != NULL)
{
fprintf(STDERR, " %lu bytes at %x\n",
fprintf(STDERR, " %lu bytes at %p\n",
(unsigned long)pinfo->size,
(unsigned int)pinfo->pointer);
pinfo->pointer);
pinfo = pinfo->next;
}
}
@@ -1885,7 +1891,12 @@ main(int argc, char *argv[])
status_dots_requested = 0;
if (i == 0 || verbose == 1 || ierror != 0)
{
fprintf(STDERR, "\n Testing %s:", inname);
#if PNG_DEBUG > 0
fprintf(STDERR, "\n");
#endif
}
kerror = test_one_file(inname, outname);
@@ -1904,21 +1915,26 @@ main(int argc, char *argv[])
#endif
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
for (k = 0; k<256; k++)
if (filters_used[k])
if (filters_used[k] != 0)
fprintf(STDERR, " Filter %d was used %lu times\n",
k, (unsigned long)filters_used[k]);
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
if (tIME_chunk_present != 0)
fprintf(STDERR, " tIME = %s\n", tIME_string);
#endif /* PNG_TIME_RFC1123_SUPPORTED */
#endif /* TIME_RFC1123 */
}
}
else
{
if (verbose == 0 && i != 2)
{
fprintf(STDERR, "\n Testing %s:", inname);
#if PNG_DEBUG > 0
fprintf(STDERR, "\n");
#endif
}
fprintf(STDERR, " FAIL\n");
ierror += kerror;
@@ -1937,8 +1953,8 @@ main(int argc, char *argv[])
while (pinfo != NULL)
{
fprintf(STDERR, " %lu bytes at %x\n",
(unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
fprintf(STDERR, " %lu bytes at %p\n",
(unsigned long)pinfo->size, pinfo->pointer);
pinfo = pinfo->next;
}
}
@@ -1976,6 +1992,24 @@ main(int argc, char *argv[])
else
fprintf(STDERR, " libpng FAILS test\n");
dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
fprintf(STDERR, " Default limits:\n");
fprintf(STDERR, " width_max = %lu\n",
(unsigned long) png_get_user_width_max(dummy_ptr));
fprintf(STDERR, " height_max = %lu\n",
(unsigned long) png_get_user_height_max(dummy_ptr));
if (png_get_chunk_cache_max(dummy_ptr) == 0)
fprintf(STDERR, " cache_max = unlimited\n");
else
fprintf(STDERR, " cache_max = %lu\n",
(unsigned long) png_get_chunk_cache_max(dummy_ptr));
if (png_get_chunk_malloc_max(dummy_ptr) == 0)
fprintf(STDERR, " malloc_max = unlimited\n");
else
fprintf(STDERR, " malloc_max = %lu\n",
(unsigned long) png_get_chunk_malloc_max(dummy_ptr));
png_destroy_read_struct(&dummy_ptr, NULL, NULL);
return (int)(ierror != 0);
}
#else