diff --git a/.github/workflows/README.md b/.github/workflows/README.md index a0772027..1683b100 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -267,7 +267,7 @@ binary. | Job | Tool | Notes | |-----|------|-------| -| `cppcheck` | `cppcheck --enable=all` on `src/` | Fails on any `error:` line. Warnings are reported but don't fail. | +| `cppcheck` | `cppcheck --enable=all` on `src/` | Fails on any `error:` line, or on a file cppcheck could not analyse (`noValidConfiguration`). Warnings are reported but don't fail. | | `scan-build` | `clang --analyze` via `scan-build` | Currently fails only if bug count > 50 (rolling baseline). HTML report uploaded as artifact. | | `infer` | Facebook Infer | Currently fails only if issue count > 100. CSV + text report uploaded. | @@ -409,6 +409,7 @@ for review). | Nightly Slack alert: ` FIPS` failed | The corresponding `.yml` job log → "Test with wolfProvider" step. The OSP patch in `wolfssl/osp` is the usual fix site. | | Sanitizer report (ASan/UBSan/TSan) | `sanitizers.yml` → "Run wolfprov unit tests (make test) under sanitizers" step. The first stack frame inside wolfProvider source is the bug. | | Static analysis report | Download the `scan-build-results` / `cppcheck-results` / `infer-results` artifact from the workflow run. | +| `cppcheck could not analyse: ` | Rerun the "Run cppcheck" command from `static-analysis.yml` locally with `-v` on a listed file to see which `#error` or `#if` stopped every configuration. The usual fix is another `-D`/`-U` there; those flags work around the bookworm image's cppcheck 2.10, so revisit them when it is upgraded. | | Container image change isn't picked up | `publish-test-deps-image.yml` only fires on push to master under `docker/wolfprovider-test-deps/**`. Manually dispatch it if you need to force a rebuild. | ## Layout reference diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index e3ffd818..678b7b0f 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -73,30 +73,53 @@ jobs: OPENSSL_INC="$PWD/openssl-install/include" WOLFSSL_INC="$PWD/wolfssl-install/include" WOLFPROV_INC="$PWD/include" - + + # Under -j, cppcheck runs its whole-program checks only with a build dir + rm -rf cppcheck-build + mkdir cppcheck-build + # Run cppcheck on source files only (tests can be analyzed separately if needed) - # Use --force and suppress noValidConfiguration to proceed even with incomplete config - cppcheck \ + # The *_MAX values stand in for , which wolfSSL's sp_int.h needs. + # cppcheck 2.10 cannot evaluate __has_include(); library #ifdefs add no configurations. + # cppcheck's own exit status goes to cppcheck-rc.txt; the pipeline status is tee's. + rm -f cppcheck-rc.txt + { cppcheck \ --enable=all \ --suppress=missingIncludeSystem \ --suppress=unusedFunction \ --suppress=unmatchedSuppression \ - --suppress=noValidConfiguration \ --inline-suppr \ --force \ --error-exitcode=0 \ -I "$OPENSSL_INC" \ -I "$WOLFSSL_INC" \ -I "$WOLFPROV_INC" \ + --config-exclude="$OPENSSL_INC" \ + --config-exclude="$WOLFSSL_INC" \ + -DUCHAR_MAX=255 \ + -DUSHRT_MAX=65535 \ + -DUINT_MAX=4294967295U \ + -DULONG_MAX=18446744073709551615UL \ + -DULLONG_MAX=18446744073709551615ULL \ + -U__has_include \ + -j "$(nproc)" \ + --cppcheck-build-dir=cppcheck-build \ --platform=unix64 \ - src/ 2>&1 | tee cppcheck-output.txt || true - - # Display output (filter out noValidConfiguration messages and progress) - grep -v "noValidConfiguration" cppcheck-output.txt | \ - grep -v "^Checking " | \ + src/ 2>&1 || echo $? > cppcheck-rc.txt; } | tee cppcheck-output.txt || true + + # Display output (filter out progress) + grep -v "^Checking " cppcheck-output.txt | \ grep -v "^[0-9]*/[0-9]* files checked" | \ grep -v "^nofile:0:0: information:" || true - + + # Findings do not change the exit status (--error-exitcode=0), so non-zero + # means cppcheck itself failed, e.g. crashed before checking every file + CPPCHECK_RC=$(cat cppcheck-rc.txt 2>/dev/null || echo 0) + if [ "$CPPCHECK_RC" -ne 0 ]; then + echo "cppcheck exited with status $CPPCHECK_RC" + exit 1 + fi + # Count errors and warnings (count lines with error:/warning: that are actual issues) # Use wc -l for more reliable counting, and strip whitespace ERROR_COUNT=$(grep -E "^src/.*:[0-9]+:[0-9]+:.*error:" cppcheck-output.txt 2>/dev/null | wc -l | tr -d '[:space:]' || echo "0") @@ -108,6 +131,14 @@ jobs: echo "cppcheck found $ERROR_COUNT errors and $WARNING_COUNT warnings" + # Fail if any file had no valid configuration, i.e. was not analysed + NOT_ANALYZED=$(grep "\[noValidConfiguration\]" cppcheck-output.txt | cut -d: -f1 | sort -u) + if [ -n "$NOT_ANALYZED" ]; then + echo "cppcheck could not analyse:" + echo "$NOT_ANALYZED" + exit 1 + fi + # Fail only if critical errors found (adjust threshold as needed) if [ "${ERROR_COUNT}" -gt 0 ] 2>/dev/null; then echo "cppcheck found errors"