Skip to content

feat: expand MISRA-C rule coverage; ASIL-scale the accredited-tool note - #114

Merged
SoundMatt merged 2 commits into
mainfrom
feat/misra-rule-expansion
Aug 13, 2026
Merged

feat: expand MISRA-C rule coverage; ASIL-scale the accredited-tool note#114
SoundMatt merged 2 commits into
mainfrom
feat/misra-rule-expansion

Conversation

@SoundMatt

Copy link
Copy Markdown
Owner

Fixes #108. Part of the ASIL-scaling initiative tracked in #103.

Summary

Adds two new pattern-based lint rules, closing two of cmd_misra.c's previously-uncovered MISRA-C:2012 gaps:

  • CFUSA-L011 (Rule 7.1): octal constants. A 0 immediately followed by another digit, with no identifier/. character directly before it, is an octal integer constant in C. The boundary-before check alone correctly rejects hex literals (the 0 in 0x0A is preceded by x), plain zero, and floats (0.5) without any hex/float-specific logic.
  • CFUSA-L012 (Rule 20.4): a macro defined with the same name as a C99 keyword (e.g. #define int short).

Both wired into cmd_lint.c's rule table and cmd_misra.c's coverage map (R7.1/R20.4 now show CFUSA-L011/CFUSA-L012 instead of GAP).

The accredited-tool note

Per explicit direction, this does not change docs/standards/misra-c.md's recommendation to supplement with an accredited third-party MISRA-C tool (LDRA, PC-lint Plus, Polyspace) for production-ASIL compliance — c-FuSa remains a pattern-based subset, not a certification-grade checker.

Instead, cfusa misra now ASIL-scales how strongly that recommendation is stated: a project declaring iso26262:ASIL-C or ASIL-D in .fusa.json's standards[] gets a REQUIRED (not RECOMMENDED) accreditedToolNote in both text and JSON output, using the same declared-ASIL convention comp_threshold()/HARA005 already use.

$ cfusa misra --dir <asil-d-project>
...
REQUIRED: this project declares ASIL-C/D. cfusa's pattern-based
MISRA-C subset is NOT sufficient for a production ASIL-C/D MISRA-C
compliance claim — an accredited MISRA-C tool (e.g. LDRA, PC-lint
Plus, Polyspace) is required, not merely recommended.

Testing

  • 14 new regression tests: 8 for L011/L012 positive/negative/edge cases (hex literal, plain zero, float, octal-in-string, keyword-prefixed non-keyword identifier like integer) in tests/test_lint_extended.c, plus 3 in tests/test_cli_commands.c covering the coverage-table update and both tiers of the ASIL-scaled note.
  • Manually swept the new rules across c-FuSa's own codebase: 68 CFUSA-L011 findings, all genuine POSIX file-mode octal literals (0600/0700/0755) — exactly Rule 7.1's intended catch, zero false positives; 0 CFUSA-L012 findings (no keyword-named macros exist in this codebase).
  • ctest: 42/42 passing.
  • cfusa check --dir .: 0 errors (new findings are WARNING-severity, same category convention as the existing lint rules).
  • cfusa trace --dir .: new REQ-LINT015/REQ-LINT016/REQ-MISRA002 traced + tested, no dangling references, no id collisions (double-checked after catching a near-miss on Unify cyclomatic-complexity threshold between cfusa comp's --asil-* aliases and check's automatic COMP001 gate #107).

🤖 Generated with Claude Code

…te (#108)

Adds two new pattern-based lint rules, closing two of cmd_misra.c's
previously-uncovered MISRA-C:2012 gaps:

- CFUSA-L011 (Rule 7.1): octal constants. A '0' immediately followed
  by another digit, with no identifier/'.' character directly before
  it, is an octal integer constant in C. The boundary-before check
  alone correctly rejects hex literals (the '0' in 0x0A is preceded
  by 'x'), plain zero, and floats (0.5) without any hex/float-specific
  logic.
- CFUSA-L012 (Rule 20.4): a macro defined with the same name as a C99
  keyword (e.g. '#define int short').

Both wired into cmd_lint.c's rule table and cmd_misra.c's coverage
map (R7.1/R20.4 now show CFUSA-L011/L012 instead of a gap).

Per explicit direction: this does NOT change docs/standards/misra-c.md's
recommendation to supplement with an accredited third-party MISRA-C
tool (LDRA, PC-lint Plus, Polyspace) for production-ASIL compliance --
c-FuSa remains a pattern-based subset, not a certification-grade
checker. Instead, cfusa misra now ASIL-scales how strongly that
recommendation is stated: a project declaring iso26262:ASIL-C or
ASIL-D in .fusa.json's standards[] gets a REQUIRED (not RECOMMENDED)
accreditedToolNote in both text and JSON output, using the same
declared-ASIL convention comp_threshold()/HARA005 already use.

14 new regression tests: 8 for L011/L012 positive/negative/edge cases
(hex literal, plain zero, float, octal-in-string, keyword-prefixed
non-keyword identifier) in tests/test_lint_extended.c, plus 3 in
tests/test_cli_commands.c covering the coverage-table update and both
tiers of the ASIL-scaled note.

Manually swept the new rules across c-FuSa's own codebase: 68 CFUSA-L011
findings, all genuine POSIX file-mode octal literals (0600/0700/0755) —
exactly Rule 7.1's intended catch, zero false positives; 0 CFUSA-L012
findings (no keyword-named macros exist). cfusa check still reports 0
errors (these are WARNING-severity lint findings, unchanged category
convention).

Part of #103.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com>

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c-FuSa found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Comment thread tests/test_cli_commands.c Fixed
Same pattern as the earlier c-FuSa fixes: a raw fopen(path, "w") in
the new ASIL-scaled-note test's fixture creation was flagged as
potentially world-writable (CWE-732-adjacent) by CodeQL.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com>
@SoundMatt
SoundMatt merged commit c96cf5c into main Aug 13, 2026
10 checks passed
SoundMatt added a commit that referenced this pull request Aug 14, 2026
L003 (MISRA-C 2012 Rule 21.3, dynamic memory) matched malloc/calloc/
realloc/free with a plain strstr(), so "free(" also matched inside any
custom cleanup function ending in "_free(" (e.g. cfusa_report_free()).
Measured project-wide: 464 findings, 61% of which were this class of
false positive plus quoted example-code text. Now requires a
non-identifier boundary immediately before the match (same technique
L011 uses for its octal-constant check) and skips string-literal
content. Cuts the self-scan from 464 to 133 genuine findings.

Also ASIL-scales L003's severity: ISO 26262-6 lists avoiding dynamic
memory allocation as "highly recommended" at ASIL-C/D but only
"recommended" at QM/A/B, so a declared ASIL-C/D project now gets a hard
SEV_ERROR instead of the uniform SEV_WARNING every project got before.

Moved declared-ASIL extraction (previously a cmd_misra.c-local
declared_asil_rank(), added in PR #114/issue #108) into severity.h as
cfusa_declared_asil_rank(), so cmd_lint.c's L003 can share it instead of
re-deriving it locally -- exactly the drift severity.h's own header
comment warns against.

New requirement REQ-LINT017 covers the precision fix and ASIL scaling;
existing REQ-LINT005/REQ-MISRA002 traces preserved. 8 new tests added
(custom-_free()-suffixed silence, string-literal silence, genuine call
still fires beside a custom one, and 4 severity-by-ASIL cases).

Also fixes a pre-existing CodeQL cpp/world-writable-file-creation alert
in tests/test_lint_rules2.c: three helper functions in this file used
bare fopen(path, "w") (mode 0666); switched to cfusa_fopen_write()
(explicit 0600), the established pattern from prior fclose/permission
cleanups this session. Surfaced by this PR because adding new code
shifted a pre-existing helper into the diff's changed-line range.

All 42 test suites pass. cfusa trace: 369/371 clean, no dangling refs.
cfusa check on the project itself: 0 errors (project declares no
specific ASIL, so L003 stays at its prior WARNING severity here).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com>
SoundMatt added a commit that referenced this pull request Aug 14, 2026
L003 (MISRA-C 2012 Rule 21.3, dynamic memory) matched malloc/calloc/
realloc/free with a plain strstr(), so "free(" also matched inside any
custom cleanup function ending in "_free(" (e.g. cfusa_report_free()).
Measured project-wide: 464 findings, 61% of which were this class of
false positive plus quoted example-code text. Now requires a
non-identifier boundary immediately before the match (same technique
L011 uses for its octal-constant check) and skips string-literal
content. Cuts the self-scan from 464 to 133 genuine findings.

Also ASIL-scales L003's severity: ISO 26262-6 lists avoiding dynamic
memory allocation as "highly recommended" at ASIL-C/D but only
"recommended" at QM/A/B, so a declared ASIL-C/D project now gets a hard
SEV_ERROR instead of the uniform SEV_WARNING every project got before.

Moved declared-ASIL extraction (previously a cmd_misra.c-local
declared_asil_rank(), added in PR #114/issue #108) into severity.h as
cfusa_declared_asil_rank(), so cmd_lint.c's L003 can share it instead of
re-deriving it locally -- exactly the drift severity.h's own header
comment warns against.

New requirement REQ-LINT017 covers the precision fix and ASIL scaling;
existing REQ-LINT005/REQ-MISRA002 traces preserved. 8 new tests added
(custom-_free()-suffixed silence, string-literal silence, genuine call
still fires beside a custom one, and 4 severity-by-ASIL cases).

Also fixes a pre-existing CodeQL cpp/world-writable-file-creation alert
in tests/test_lint_rules2.c: three helper functions in this file used
bare fopen(path, "w") (mode 0666); switched to cfusa_fopen_write()
(explicit 0600), the established pattern from prior fclose/permission
cleanups this session. Surfaced by this PR because adding new code
shifted a pre-existing helper into the diff's changed-line range.

All 42 test suites pass. cfusa trace: 369/371 clean, no dangling refs.
cfusa check on the project itself: 0 errors (project declares no
specific ASIL, so L003 stays at its prior WARNING severity here).

Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com>
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.

Expand MISRA-C pattern-rule coverage; ASIL-scale the accredited-tool recommendation (don't remove it)

2 participants