feat: expand MISRA-C rule coverage; ASIL-scale the accredited-tool note - #114
Merged
Conversation
…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>
There was a problem hiding this comment.
c-FuSa found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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. A0immediately 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 (the0in0x0Ais preceded byx), 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 andcmd_misra.c's coverage map (R7.1/R20.4 now showCFUSA-L011/CFUSA-L012instead ofGAP).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 misranow ASIL-scales how strongly that recommendation is stated: a project declaringiso26262:ASIL-CorASIL-Din.fusa.json'sstandards[]gets aREQUIRED(notRECOMMENDED)accreditedToolNotein both text and JSON output, using the same declared-ASIL conventioncomp_threshold()/HARA005 already use.Testing
integer) intests/test_lint_extended.c, plus 3 intests/test_cli_commands.ccovering the coverage-table update and both tiers of the ASIL-scaled note.CFUSA-L011findings, all genuine POSIX file-mode octal literals (0600/0700/0755) — exactly Rule 7.1's intended catch, zero false positives; 0CFUSA-L012findings (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 .: newREQ-LINT015/REQ-LINT016/REQ-MISRA002traced + 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