Comment #6 on issue 621 by j...@
jguk.org: BuildHuffmanTable could replace assert with if() for safety
https://bugs.chromium.org/p/webp/issues/detail?id=621#c6Pascal, you're completely right, the patch is the easy part.
My notes below, due to points (5) and (6) particularly - I would recommend putting in the check. I've included my build output where two of the asserts appear to be needed to be if() in this investigation I did.
When I consider Formal Verification for libraries like this, I would think if the code meets the requirements of Functional Safety for a Safety Critical System. Where a Safety Critical System could be decoding WebP files for an automotive display, aviation, defence, health care.
Considering the code, there are a few areas I would focus on :-
1. Testing, so while there is assert() present in Release builds (!NDEBUG), it depends what WebP files are tested in such a build (we couldn't link to a build in safety critical software that used assert() because it might call abort()).
2. If WebP files in the wild tested (perhaps as part of integration testing)
3. Files that haven't been created yet, someone could create a file in 2024 that overflows a buffer in a 2023 released version of WebP decoder.
4. The 'cost' of a branch instruction (not jumped), typically one cycle. It's a very low cost, for 100% certainty that the software will detect an invalid parameter. It feels like premature optimization to take out such checks.
5. We don't want to wait for corrupt files to crash safety critical systems, or cyber security exploits, it's safer just to be 100% careful in the code we can control.
6. Does the compiler optimize out the checks? It doesn't, which means it's not dead code. There would be no 'cost' if the optimizer removed the checks.
Due to these reasons I would recommend putting in the checks.
src/utils/huffman_utils.c: In function ‘BuildHuffmanTable’:
src/utils/huffman_utils.c:88:84: error: call to ‘_stop_compile’ declared with attribute error: build stopped
88 | #define compile_assert(condition, description) {if(!_check_condition(condition)) { _stop_compile();}}
| ^~~~~~~~~~~~~~~
src/utils/huffman_utils.c:119:3: note: in expansion of macro ‘compile_assert’
119 | compile_assert((root_table != NULL && sorted != NULL) || (root_table == NULL && sorted == NULL), "");
| ^~~~~~~~~~~~~~
src/utils/huffman_utils.c:88:84: error: call to ‘_stop_compile’ declared with attribute error: build stopped
88 | #define compile_assert(condition, description) {if(!_check_condition(condition)) { _stop_compile();}}
| ^~~~~~~~~~~~~~~
src/utils/huffman_utils.c:120:3: note: in expansion of macro ‘compile_assert’
120 | compile_assert(root_bits > 0, "");