| #!/bin/sh |
| |
| st=0 # exit status (set to 1 if a test fails) |
| skipped= |
| fail="**FAIL**" |
| skip="**SKIP**" |
| success=" SUCCESS" |
| 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 |
| |
| # 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: the test file (a bad PNG which must produce a warning, etc) |
| # $2: 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. |
| 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 -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 "$file" 'IDAT: Read palette index exceeding num_palette' | |
| check_stdout "$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 |