| #!/bin/sh | |
| st=0 # exit status (set to 1 if a test fails) | |
| skipped= | |
| fail="**FAIL**" | |
| skip="**SKIP**" | |
| success=" SUCCESS" | |
| # The following check allows this script to know if write of PNG files is | |
| # **not** supported, This allows more simple skipping of the read/write | |
| # palette index check below. | |
| while read line | |
| do | |
| # Add specific tests here. Only 'WRITE' support needs to be checked at | |
| # present. Note that there is always a single space between 'define' and | |
| # 'PNG...'; pnglibconf.h is machine generated. | |
| case "$line" in | |
| "define PNG_WRITE_SUPPORTED") write=1;; | |
| esac | |
| done <./pnglibconf.h | |
| # | |
| TEST(){ | |
| # Try to make the log file easier to read: | |
| echo "=============== pngtest $* ====================" | |
| ./pngtest "$@" | |
| status=$? | |
| case "$status" in | |
| 0) test_status="$success";; | |
| 77) test_status="$skip" | |
| skipped=1;; | |
| *) test_status="$fail" | |
| st="$status";; | |
| esac | |
| echo "===============$test_status $* ====================" | |
| return "$status" | |
| } | |
| # The "standard" test | |
| TEST --strict "${srcdir}"/pngtest.png | |
| # PNG-3 tests | |
| TEST --strict "${srcdir}"/contrib/testpngs/png-3/*.png | |
| # Various crashers | |
| # Use --relaxed because some come from fuzzers that don't maintain CRCs | |
| TEST --relaxed "${srcdir}"/contrib/testpngs/crashers/badcrc.png | |
| # Use --xfail because there is no reliable way of disabling these errors | |
| # (Adler32 checking cannot be switched off on all builds and there is no | |
| # provision for turning the other checks into warnings.) | |
| TEST --xfail "${srcdir}"/contrib/testpngs/crashers/badadler.png | |
| TEST --xfail "${srcdir}"/contrib/testpngs/crashers/bad_iCCP.png | |
| TEST --xfail "${srcdir}"/contrib/testpngs/crashers/empty_ancillary_chunks.png | |
| for file in "${srcdir}"/contrib/testpngs/crashers/huge_*_chunk.png | |
| do | |
| TEST --xfail "$file" | |
| done | |
| for file in "${srcdir}"/contrib/testpngs/crashers/huge_*safe_to_copy.png | |
| do | |
| TEST --xfail "$file" | |
| done | |
| TEST --xfail "${srcdir}"/contrib/testpngs/crashers/huge_IDAT.png | |
| # Regression tests for required warnings (or errors): | |
| check_stdout(){ | |
| # $1: non-empty if this test is supported else an empty string | |
| # $2: the test file (a bad PNG which must produce a warning, etc) | |
| # $3: a string which must occur at the end of line on stdout for success | |
| # result: an error message on descriptor 3 if the string is NOT found | |
| # | |
| # WARNING: when this script is executed on MSYS2 (Windows Cygwin variant) | |
| # pngtest outputs lines terminated with <cr><lf> however the MSYS2 shell | |
| # expects <lf> (\n) terminated lines so the <cr> ends up in the shell | |
| # variable 'line' below. The pattern matching ignores this because of the | |
| # '*' at the end of the pattern match. | |
| supported="$1" | |
| shift | |
| found= | |
| skipped= | |
| while read line | |
| do | |
| case "$line" in | |
| *"$2"*) found=1;; | |
| *"TEST SKIPPED"*) skipped=1;; | |
| esac | |
| echo "$line" # preserve the original output verbatim | |
| done | |
| # output the missing warning on descriptor 3: | |
| test -n "$supported" -a -z "$found" -a -z "$skipped" && echo "$1: $2" >&3 | |
| } | |
| # NOTE: traditionally the Bourne shell executed the last element in a pipe | |
| # sequence in the original shell so it could set variables in the original | |
| # shell however this is not reliable and doesn't work in bash. | |
| # | |
| # It *is* reliable to use the actual exit status of the last command in | |
| # the pipeline. | |
| exec 4>&1 # original stdout - the log file | |
| { | |
| exec 3>&1 # stdout is the pipe at this point | |
| fail=" FAIL(EXPECTED)" # runtime scope | |
| success=" SUCCESS(UNEXPECTED)" # there should be a write error | |
| for file in "${srcdir}"/contrib/testpngs/badpal/*.png | |
| do | |
| # The exit code is ignored here, the test is that the particular errors | |
| # (warnings) are produced. The original output still ends up in the log | |
| # file. | |
| { | |
| TEST "$file" | |
| test "$?" -eq 77 && echo "TEST SKIPPED" | |
| } | | |
| check_stdout "supported" "$file" \ | |
| 'IDAT: Read palette index exceeding num_palette' | | |
| check_stdout "$write" "$file" \ | |
| 'Wrote palette index exceeding num_palette' >&4 | |
| done | |
| exec 3>&- | |
| } | { | |
| # This may not be a sub-shell, if it is 'st' is undefined and the exit | |
| # just ends up as 'exit'. | |
| while read error | |
| do | |
| echo "MISSING REPORT: $error" | |
| st=1 | |
| done | |
| exit $st | |
| } || st=$? | |
| test "$st" -gt 0 && exit "$st" | |
| test -n "$skipped" && exit 77 | |
| exit 0 |