Skip to content

Conversation

@wrp
Copy link
Contributor

@wrp wrp commented Jan 15, 2026

Add a simplistic test framework. testprog only exercises about 16% of the code (as reported by gcov), and 22 files have zero coverage. This adds some basic unit testing to exercise a larger chunk of the code base to protect against regressions.

A few issues discovered while developing the tests are mentioned in tests/ISSUES

@wrp wrp force-pushed the test-framework branch 2 times, most recently from 15514cb to 1866a9e Compare January 15, 2026 21:34
@esabol
Copy link
Contributor

esabol commented Jan 15, 2026

This is a huge contribution. Unit tests have long been much needed. Thank you!

The CI is currently failing with:

ERROR: files left in build directory after distclean:
./test_putcoluj2.fits

@esabol
Copy link
Contributor

esabol commented Jan 15, 2026

A few issues discovered while developing the tests are mentioned in tests/ISSUES

I recommend opening separate issues for these in https://github.com/HEASARC/cfitsio/issues/

I would then delete the ISSUES file from the pull request.

@wrp
Copy link
Contributor Author

wrp commented Jan 16, 2026

Removed ISSUES and created issues 117-119. PTAL

@wrp
Copy link
Contributor Author

wrp commented Jan 16, 2026

Checking the test failures on ubuntu.

wrp added 27 commits January 17, 2026 18:06
The pseudo-random number generator in test_rcomp_high_entropy() used
signed integer arithmetic that overflows when i >= 2:

    original[i] = ((i * 1103515245 + 12345) >> 16) & 0x7FFF;

The multiplication i * 1103515245 exceeds INT_MAX (2147483647) at i=2,
producing 2207030490 which cannot be represented as a signed int.  This
is undefined behavior per the C standard (C11 6.5/5).

GCC on Ubuntu ARM with -O2 exploits this UB via aggressive loop
optimizations (-Waggressive-loop-optimizations), causing the test
to abort with a core dump during distcheck.  The compiler warning:

    warning: iteration 2 invokes undefined behavior

The fix uses unsigned arithmetic throughout:

    original[i] = (((unsigned)i * 1103515245U + 12345U) >> 16) & 0x7FFF;

This produces identical pseudo-random values but with well-defined
overflow semantics (modulo 2^32 per C11 6.2.5/9).
The fits_rcomp, fits_rcomp_short, and fits_rcomp_byte functions do not
perform end-of-buffer checking.  As documented in ricecomp.c:

    "Note that beginning with CFITSIO v3.08, EOB checking was removed
    to improve speed, and so now the input compressed bytes buffers
    must have been allocated big enough so that they will never be
    overflowed."

The removed tests passed intentionally undersized buffers expecting
the library to detect this and return an error.  Instead, the library
writes past the buffer bounds, causing stack corruption.  This was
detected on Linux by FORTIFY_SOURCE/glibc, triggering SIGABRT.

The test_rdecomp_buffer_too_small test is retained since decompression
reads from the buffer (bounded by clen parameter) rather than writing.
@esabol
Copy link
Contributor

esabol commented Jan 20, 2026

All CI workflows are passing now. LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants