* avoid undefined behavior from UNREACHABLE on reachable code paths
UNREACHABLE expands to __assume(false) / __builtin_unreachable() in
release builds, which is undefined behavior if the code is ever actually
reached. Many UNREACHABLE sites only guard against unexpected-but-
possible runtime states (values from tables, mission/save files, network
packets, scripting, or user input), so reaching them should degrade
gracefully rather than invoke UB.
Replace UNREACHABLE with Assertion(false, ...) at all such sites. It
still pops an error in debug builds, but in release it is a harmless
no-op that simply falls through to the following code. Sites that are
genuinely unreachable by local invariants (e.g. a switch over a bounded
random number) are left as UNREACHABLE.
A few converted sites had no safe fall-through -- an uninitialized read,
null dereference, or null call would have followed -- so they also get a
minimal recovery: initialize the value, guard the dereference, return
early, or skip the offending item.
Where the converted site was a simple guard of the form
if (x) { Assertion(false, ...); return; }
hoist the check onto the invariant instead:
Assertion(!x, ...);
if (x) { return; }
This states the expectation directly and shows the offending value in
the debug popup, while keeping the same graceful runtime degradation.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* addendum
After consultation with Lafiel, use UNREACHABLE in situations that are effectively impossible even if not provably impossible. UNREACHABLE = "this shouldn't ever happen"; Assertion = "if this ever happens, it's a coding error". Also fix a few other sites and change a couple to Warnings.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Since event music soundtracks use the exact file extension specified (see #5567), the validity check should also use the exact file extension specified.
Also, move the validity check to after parsing has completed because extensions may be overridden.
Currently, menu music will trim the extension and look for both OGG and WAV files, but event music will use the exact extension specified. This is intended but could lead to unexpected results in mods, so display a warning for the modder.
* add subfolder support to cfile
* sort files in VP archives before indexing them
* fix indexing of sub-subfolders
* remove unused 8B22K & 16B11K sound path types
* add more items to skip subfolder scanning
* fix windows build issues
* fix unit tests by allowing 0-byte files to be indexed
* fix file indexing on windows
* add test for cfile subfolders
* remove specific 'markup' and 'css' interface subfolders
They aren't directly referenced anywhere by pathtype and the new
subfolder code will continue to index and load files from them
* add player binds to list of always-root locations
* remove file-based localization support
An alternative is left in place for old fonts, as that was the only place
it appeared to be used.
This method of file localization conflicts with subfolder support however
so if it's needed in the future then changes to the subfolder code will
be necessary.
* add subfolder support to cf_find_file_location_ext()
* add subfolder tests for cf_find_file_location*()
* add shlwapi to needed win32 libs
* small bit of cleanup
* add subfolder support to cf_get_file_list()
* add tests for cfile subfolder lists
* report files that might be shadowed
* fix issue with lists when a filter is used
Also fixes discrepancy in older cf_get_file_list() when a sub path
is specified (should be used in all cases, not just glob).
* address review suggestions
This does some refactoring to make it possible to cimpile and run FSO
without needing to link to FFmpeg. Since that eliminates support for
cutscenes or sound this is mostly useful for running a standalone server
which has no need for this anyway.
This reduces the image size of the standalone Docker image to only 20MB
and also resolves any licensing issues that might have existed.
The amount of output parameters is becoming quite large which makes it
harder to add new input parameters. For that reason I converted the
existing output parameters to a struct which cleans up the function
signature a lot.
This can be used for mark parts of the code which should be unreachable
in normal execution. In debug mode, if such a statement is reached an
Error dialog is shown which aborts the execution. In release mode the
macro is replaced with a compiler specific expression that lets the
compiler know that this part is unreachable which allows it to optimize
the code better.
This allows to use more complex file structures in the executable
without requiring that those exist as real files. The rest of the code
does not need to handle the difference between a default file and a real
file anymore which means that it's now possible to embed image files
into the executable since bmpman only needs to use the standard CFile
API.
I added two tests which check if the default file can be found and
opened and if a mod file overrides the default file which should always
be possible.
ADPCM playback was broken by #991 when an older FFmpeg version (< 3.1)
was used. The newer version has a better API for handling decoder that
return multiple frames of data per packet which I already used. However,
I didn't bother implementing that for the older API since I haven't seen
a decoder that actually returned multiple frames per packet but ADPCM is
such a decoder. This fixes that by implementing the correct behavior
with the old API.
This is the first step towards moving all audio decoding to FFmpeg which
will reduce the amount of external code we will need to include. This
only replaces the AudioStream code with an FFmpeg based solution which
should make the code easier to review.