[libpng16] Added "tunknown" test and corrected a logic error in

png_handle_unknown() when SAVE support is absent.  Moved the shell test
scripts for contrib/libtests from the libpng top directory to contrib/libtests.
png_handle_unknown() must always read or skip the chunk, if
SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set
a user callback an unknown chunk will not be read, leading to a read
error, which was revealed by the "tunknown" test.
This commit is contained in:
John Bowler
2012-08-17 15:30:29 -05:00
committed by Glenn Randers-Pehrson
parent 3c1f6983c5
commit d0eef28ee1
10 changed files with 138 additions and 36 deletions

0
contrib/libtests/gentests.sh Normal file → Executable file
View File

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# Run the simplified API tests
err=0
echo >> pngtest-log.txt
echo "============ pngstest.sh ==============" >> pngtest-log.txt
echo "Running test-pngstest.sh"
for image in ${srcdir}/contrib/pngsuite/*.png
do
for opts in ""
do
if ./pngstest --strict --log "$@" $opts $image >>pngtest-log.txt 2>&1
then
echo " PASS: pngstest $opts $image"
else
echo " FAIL: pngstest $opts $image"
err=1
fi
done
done
exit $err

View File

@@ -0,0 +1,21 @@
#!/bin/sh
#
# Run a sequence of gamma tests quietly
err=0
echo >> pngtest-log.txt
echo "============ pngvalid-full.sh ==============" >> pngtest-log.txt
echo "Running test-pngvalid-full.sh"
for gamma in threshold transform sbit 16-to-8 background alpha-mode "transform --expand16" "background --expand16" "alpha-mode --expand16"
do
if ./pngvalid "$@" --gamma-$gamma >> pngtest-log.txt 2>&1
then
echo " PASS: pngvalid" "$@" "--gamma-$gamma"
else
echo " FAIL: pngvalid" "$@" "--gamma-$gamma"
err=1
fi
done
exit $err

View File

@@ -0,0 +1,30 @@
#!/bin/sh
#
# Run a sequence of tests quietly, without the slow
# gamma tests
err=0
echo >> pngtest-log.txt
echo "============ pngvalid-simple.sh ==============" >> pngtest-log.txt
echo "Running test-pngvalid-simple.sh"
# The options to test are:
#
# standard tests with and without progressive reading and interlace
# size images with and without progressive reading
# transform tests (standard, non-interlaced only)
#
for opts in "--standard" "--standard --progressive-read" \
"--standard --interlace" "--standard --progressive-read --interlace" \
"--size" "--size --progressive-read" \
"--transform"
do
if ./pngvalid "$@" $opts >> pngtest-log.txt 2>&1
then
echo " PASS: pngvalid" "$@" $opts
else
echo " FAIL: pngvalid" "$@" $opts
err=1
fi
done
exit $err

View File

@@ -11,12 +11,9 @@
*
* NOTES:
* This is a C program that is intended to be linked against libpng. It
* generates bitmaps internally, stores them as PNG files (using the
* sequential write code) then reads them back (using the sequential
* read code) and validates that the result has the correct data.
*
* The program can be modified and extended to test the correctness of
* transformations performed by libpng.
* allows the libpng unknown handling code to be tested by interpreting
* arguemnts to save or discard combinations of chunks. The program is
* currently just a minimal validation for the built-in libpng facilities.
*/
#include <stdlib.h>
@@ -25,6 +22,8 @@
#include <png.h>
#ifdef PNG_READ_SUPPORTED
#if PNG_LIBPNG_VER < 10500
/* This deliberately lacks the PNG_CONST. */
typedef png_byte *png_const_bytep;
@@ -365,11 +364,20 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/)
if (chunk >= 0)
{
png_byte name[5];
/* These #if tests have the effect of skipping the arguments
* if SAVE support is unavailable - we can't do a useful test
* in this case, so we just check the arguments! This could
* be improved in the future by using the read callback.
*/
# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
png_byte name[5];
memcpy(name, chunk_info[chunk].name, 5);
png_set_keep_unknown_chunks(png_ptr, option, name, 1);
chunk_info[chunk].keep = option;
memcpy(name, chunk_info[chunk].name, 5);
png_set_keep_unknown_chunks(png_ptr, option, name, 1);
chunk_info[chunk].keep = option;
# else
(void)option;
# endif
continue;
}
@@ -378,8 +386,10 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/)
case 7: /* default */
if (memcmp(argv[i], "default", 7) == 0)
{
png_set_keep_unknown_chunks(png_ptr, option, NULL, 0);
def = option;
# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
png_set_keep_unknown_chunks(png_ptr, option, NULL, 0);
def = option;
# endif
continue;
}
@@ -388,15 +398,21 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/)
case 3: /* all */
if (memcmp(argv[i], "all", 3) == 0)
{
png_set_keep_unknown_chunks(png_ptr, option, NULL, -1);
def = option;
# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
png_set_keep_unknown_chunks(png_ptr, option, NULL, -1);
def = option;
for (chunk = 0; chunk < NINFO; ++chunk)
if (chunk_info[chunk].all)
chunk_info[chunk].keep = option;
for (chunk = 0; chunk < NINFO; ++chunk)
if (chunk_info[chunk].all)
chunk_info[chunk].keep = option;
# endif
continue;
}
break;
default: /* some misplaced = */
break;
}
}
@@ -499,7 +515,7 @@ check_handling(const char *file, int def, png_uint_32 chunks, png_uint_32 known,
int i = find_by_flag(flag);
int keep = chunk_info[i].keep;
const char *type;
const char *error = NULL;
const char *errorx = NULL;
if (chunk_info[i].unknown)
{
@@ -513,34 +529,38 @@ check_handling(const char *file, int def, png_uint_32 chunks, png_uint_32 known,
type = "UNKNOWN (specified)";
if (flag & known)
error = "chunk processed";
errorx = "chunk processed";
else switch (keep)
{
case PNG_HANDLE_CHUNK_AS_DEFAULT:
if (flag & unknown)
error = "DEFAULT: unknown chunk saved";
errorx = "DEFAULT: unknown chunk saved";
break;
case PNG_HANDLE_CHUNK_NEVER:
if (flag & unknown)
error = "DISCARD: unknown chunk saved";
errorx = "DISCARD: unknown chunk saved";
break;
case PNG_HANDLE_CHUNK_IF_SAFE:
if (ancillary(chunk_info[i].name))
{
if (!(flag & unknown))
error = "IF-SAFE: unknown ancillary chunk lost";
errorx = "IF-SAFE: unknown ancillary chunk lost";
}
else if (flag & unknown)
error = "IF-SAFE: unknown critical chunk saved";
errorx = "IF-SAFE: unknown critical chunk saved";
break;
case PNG_HANDLE_CHUNK_ALWAYS:
if (!(flag & unknown))
error = "SAVE: unknown chunk lost";
errorx = "SAVE: unknown chunk lost";
break;
default:
errorx = "internal error: bad keep";
break;
}
} /* unknown chunk */
@@ -555,43 +575,47 @@ check_handling(const char *file, int def, png_uint_32 chunks, png_uint_32 known,
* caught below when checking for inconsistent processing.
*/
if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
error = "!DEFAULT: known chunk processed";
errorx = "!DEFAULT: known chunk processed";
}
else /* not processed */ switch (keep)
{
case PNG_HANDLE_CHUNK_AS_DEFAULT:
error = "DEFAULT: known chunk not processed";
errorx = "DEFAULT: known chunk not processed";
break;
case PNG_HANDLE_CHUNK_NEVER:
if (flag & unknown)
error = "DISCARD: known chunk saved";
errorx = "DISCARD: known chunk saved";
break;
case PNG_HANDLE_CHUNK_IF_SAFE:
if (ancillary(chunk_info[i].name))
{
if (!(flag & unknown))
error = "IF-SAFE: known ancillary chunk lost";
errorx = "IF-SAFE: known ancillary chunk lost";
}
else if (flag & unknown)
error = "IF-SAFE: known critical chunk saved";
errorx = "IF-SAFE: known critical chunk saved";
break;
case PNG_HANDLE_CHUNK_ALWAYS:
if (!(flag & unknown))
error = "SAVE: known chunk lost";
errorx = "SAVE: known chunk lost";
break;
default:
errorx = "internal error: bad keep (2)";
break;
}
}
if (error != NULL)
if (errorx != NULL)
{
++error_count;
fprintf(stderr, "%s: %s %s %s: %s\n",
file, type, chunk_info[i].name, position, error);
file, type, chunk_info[i].name, position, errorx);
}
chunks &= ~flag;
@@ -622,6 +646,10 @@ main(int argc, const char **argv)
exit(2);
}
# ifndef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
fprintf(stderr,
"test-unknown: warning: no 'save' support so arguments ignored\n");
# endif
fp = fopen(argv[argc], "rb");
if (fp == NULL)
{
@@ -681,3 +709,13 @@ main(int argc, const char **argv)
return error_count + (strict ? warning_count : 0);
}
#else
int
main(void)
{
fprintf(stderr,
" test ignored because libpng was not built with unknown chunk support\n");
return 0;
}
#endif

View File

@@ -0,0 +1,38 @@
#!/bin/sh
#
# Run the unknown API tests
err=0
image="${srcdir}/pngtest.png"
#
# stream 4 is used for the output of the shell, pngtest-log.txt gets all the
# normal program output.
exec 4>&1 1>>pngtest-log.txt 2>&1
echo
echo "============ test-unknown.sh =============="
echo "Running test-unknown.sh" >&4
for tests in \
"discard default=discard"\
"save default=save"\
"if-safe default=if-safe"\
"vpAg vpAg=if-safe"\
"sTER sTER=if-safe"\
"IDAT default=discard IDAT=save"\
"sAPI bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save"
do
set $tests
test="$1"
shift
if ./tunknown "$@" "$image" 4>&-
then
echo " PASS: test-unknown $test" >&4
else
echo " FAIL: test-unknown $test" >&4
err=1
fi
done
exit $err