Static Analysis (MISRA C:2023 / CERT C / CWE)
Detects MISRA C:2023, SEI CERT C, and CWE violations in C files and provides AI-powered fix suggestions. Standards are opt-in per run (default: MISRA).
Detection is backed by cppcheck's misra addon, which statically detects a
subset of the rule set — 130 of the 133 recognised MISRA rules as of the
pinned cppcheck 2.20.0. Rules requiring whole-program or full semantic
analysis (8.13, 17.4, 17.5) are not detected and need manual review. See the
rule coverage matrix for the exact, machine-derived list — we
don't claim coverage we can't back up.
How It Works
- The extension sends the current file path (or code snippet) to the daemon
- The daemon invokes
cppcheckvia the Python engine, with the requested standards - Each violation is classified by standard (MISRA C:2023 / CERT C / CWE), with its CWE id where applicable
- (Optional) An LLM generates fix suggestions with diffs
Usage
From GitHub PR
The sidebar appears automatically on GitHub PR pages. Click MISRA Check to analyze the changed files.
API
curl -X POST http://localhost:9400/api/v1/analyze \
-H "Content-Type: application/json" \
-d '{
"file_path": "/path/to/source.c",
"rules": ["8.7", "15.5"],
"suggest": true,
"llm_mode": "local"
}'
The daemon forwards the same build-context and adoption flags the CLI exposes, so the extension and CI get identical analysis:
| Field | Maps to | Notes |
|---|---|---|
project |
--project |
Path to a compile_commands.json; whole-project mode (Pro, like batch). |
includes |
-I |
Array of header search paths. |
defines |
-D |
Array of NAME[=value] macros. |
undefines |
-U |
Array of macros to undefine. |
std / platform |
--std / --platform |
e.g. c11, unix64. |
rules |
--rules |
Allow-list of rule ids to report — MISRA numbers, CERT ids or CWE; empty = all. Full ruleset still runs; only the report is filtered. |
baseline |
--baseline |
Report and gate on new violations only. |
no_inline_suppress |
--no-inline-suppress |
Disable provadyne-ignore deviations (on by default). |
project and baseline paths are confined to the daemon's allowed analyze
directory; a path that escapes it is rejected with 403.
CLI
# default: MISRA C:2023 only
python -m engine.misra.checker /path/to/source.c
# all three C standards
python -m engine.misra.checker --standards misra,cert,cwe /path/to/source.c
Project-aware analysis
Analyzing a file in isolation produces false positives — unknown types, unexpanded macros and missing headers. Give the checker the build context so it parses code the way the compiler does:
# explicit include paths and defines
python -m engine.misra.checker --standards misra,cert,cwe \
-I include -I vendor/include -D NDEBUG -D TARGET_ARM=1 \
src/main.c
# whole project from a compilation database (recommended)
# CMake: cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# Make: bear -- make
python -m engine.misra.checker --standards misra,cert,cwe \
--project build/compile_commands.json
With --project, cppcheck discovers every translation unit and applies each
file's own include paths and defines from the database. Results come back in a
per-file batch envelope. Flags: -I/--include, -D/--define, -U/--undefine,
--std (e.g. c11), --platform (e.g. unix64).
In CI, the GitHub Action exposes the same via project, includes, defines
and standards inputs — see gh-action/examples/project.yml.
Baseline mode (adopt on a legacy codebase)
A repo with thousands of pre-existing violations is unusable if every PR shows all of them. Freeze the current state once, then fail only on new violations:
# 1. capture today's violations and commit the file
python -m engine.misra.checker --standards misra,cert,cwe \
--project build/compile_commands.json \
--write-baseline .provadyne-baseline.json
# 2. later runs report (and exit non-zero on) only NEW violations
python -m engine.misra.checker --standards misra,cert,cwe \
--project build/compile_commands.json \
--baseline .provadyne-baseline.json
Fingerprints are line-number independent (file + rule + normalized source line),
so unrelated edits elsewhere don't resurrect baselined findings. The filtered
output carries a baseline block (baselined / new counts), and the exit
code reflects new violations only. In CI, set the Action's baseline input —
see gh-action/examples/baseline.yml.
Report formats (--format)
The checker emits native JSON by default. Pass --format (or pipe the JSON
through the matching engine.report.* module) to get an alternative view of the
same findings:
# SARIF 2.1.0 for GitHub code scanning / IDEs
python -m engine.misra.checker --standards misra,cert,cwe file.c --format sarif
# Self-contained interactive HTML report (no external deps — opens offline)
python -m engine.misra.checker --standards misra,cert,cwe --iso26262 file.c \
--format html > report.html
The HTML report is a single file (inline CSS/JS, nothing fetched) with summary
cards, an ISO 26262-6 rollup, and client-side filtering — group by rule / file /
severity, filter by severity and standard, and free-text search. It works for
single-file and batch/project runs and surfaces baselines, deviations and rule
filters when present. Over the daemon API, request it with "output_format":
"html"; SARIF and HTML are not Pro-gated (PDF is).
Localized output (--lang, Pro)
Finding messages, ISO 26262-6 principle titles and the HTML report UI can be localized into Korean, German, Japanese or Chinese (Simplified) — a deterministic, offline catalog (no network, no LLM, no per-run cost):
python -m engine.misra.checker --standards misra,cert,cwe --iso26262 \
--lang de file.c --format html > bericht.html
The English source is always preserved in message_en (and title_en), so a
report stays bilingual and auditable. MISRA messages are keyed by rule id and
CERT messages by CERT id; any string without a catalog entry (e.g. a dynamic
CWE-only message) falls back to English. Over the daemon API this is the lang
field and requires the Pro localization feature — en (the default) is free.
Inline deviations (provadyne-ignore)
MISRA permits deviations when they are deliberate and documented. Record one directly in the source with a comment:
int *p = get_buffer(); // provadyne-ignore[EXP34-C]: p is null-checked by caller
// provadyne-ignore[8.4]: ISR vector table must have external linkage
void isr_handler(void) { /* ... */ }
provadyne-ignore— suppress all violations on the target lineprovadyne-ignore[8.4]/[8.4, EXP34-C]— suppress specific rules (MISRA rule number, CERT id, orCWE-NNN)- text after
:is the deviation rationale
A comment on its own line applies to the next line; a trailing comment applies
to its own line. Suppressed findings are removed from violations and recorded
under a deviations list (rule, line, message, reason) — the audit trail MISRA
assessors expect. The run reports a suppressed count. Disable with
--no-inline-suppress (CLI). Deviations are honored by default in CI.
Rule coverage
"MISRA C:2023 support" is only honest if it's clear which rules are actually
detected. The coverage matrix is derived empirically from the cppcheck misra
addon — not hand-maintained — and records, per recognised rule, whether the
pinned cppcheck version detects it:
# human-readable summary
python -m engine.misra.coverage
# full matrix (one row per rule)
python -m engine.misra.coverage --format markdown
# machine-readable (counts + supported/unsupported lists)
python -m engine.misra.coverage --format json
The raw data lives in engine/misra/coverage.json
(derived_from_cppcheck: "2.20.0"). Today: 130 of 133 recognised rules are
statically detected; 8.13, 17.4, 17.5 require manual review.
cppcheck version pin
Detected rules and severities are reproducible only against the cppcheck version
the matrix and golden tests were validated against — pinned as
SUPPORTED_CPPCHECK_VERSION = "2.20.0" in engine/misra/checker.py. Every
analysis result carries cppcheck_version and a cppcheck_supported boolean;
when the running cppcheck's major.minor differs from the pin, the CLI emits a
::warning:: (surfaced as a GitHub Actions annotation in CI) so drift never
passes silently.
ISO 26262-6 linkage
ISO 26262-6:2018 realises part of its software unit-design objectives through coding standards (clause 5/Table 1 — "use of language subsets" and "established coding standards"), and clause 8/Table 6 lists the unit-design principles. The checker can link each finding to the Table 6 principle it bears on, so a report shows which ISO 26262-6 objective a violation works against:
# annotate findings + add an iso_26262 rollup
python -m engine.misra.checker --standards misra,cert,cwe --iso26262 src/main.c
# the principle catalog itself
python -m engine.misra.coverage # (rule coverage)
python -m engine.misra.iso26262 --format markdown
With --iso26262, every mapped violation gains an iso_26262 block
(principle, title, reference) and the result carries an iso_26262 rollup
(mapped / unmapped counts and per-principle totals). The daemon exposes the
same via an "iso26262": true field on /api/v1/analyze.
This is evidence linkage, not a certification claim: a finding mapped to a
principle means the violation works against that objective; clearing it is
supporting evidence toward the safety case, not proof of compliance. Findings
with no established correspondence (engine/misra/iso26262_map.json) are left
unmapped rather than guessed.
Example Response
{
"file_path": "/path/to/source.c",
"violations": [
{
"rule": "8.7",
"severity": "required",
"line": 42,
"column": 5,
"message": "Objects should be defined at block scope if only accessed from a single function",
"suggestion": {
"original_code": "int32_t global_counter = 0;",
"fixed_code": "static int32_t global_counter = 0;",
"explanation": "Add static keyword to limit linkage to this translation unit",
"confidence": 0.95,
"diff": "--- a/source.c\n+++ b/source.c\n@@ -42,1 +42,1 @@\n-int32_t global_counter = 0;\n+static int32_t global_counter = 0;"
}
}
],
"analyzed_at": "2026-04-28T17:00:00Z",
"engine_version": "0.1.0",
"cppcheck_version": "2.20.0",
"cppcheck_supported": true
}
C++ (experimental, CLI)
C++ analysis runs through a separate clang-tidy backend, selected with
--language cpp:
python -m engine.misra.checker --language cpp --standards all src/widget.cpp
It surfaces two recognized C++ standards:
- CERT C++ — derived mechanically from clang-tidy's
cert-*checks. - C++ Core Guidelines — from clang-tidy's
cppcoreguidelines-*checks.
Standards tokens for C++: cert, cppcg, misra, all (CWE is not emitted by
clang-tidy's text output). MISRA C++:2023 is not claimed: clang-tidy does
not implement it natively, so the mapping is seeded empty and extended only with
verified correspondences (engine/misra/clangtidy_map.json) — positioning, not
certified coverage. Requires clang-tidy (LLVM 18) on PATH; a
compile_commands.json (project mode) is strongly recommended to avoid false
positives. Over the daemon, C++ is selected by the language field (or
auto-detected from the file extension) and gated behind the Pro cpp_analysis
feature; the browser extension already sends language: cpp for C/C++ files, so
clicking MISRA Check on a .cpp file routes to clang-tidy.
Rust (experimental, CLI)
Rust analysis runs through a clippy backend (MIT/Apache — commercially
clean), selected with --language rust:
python -m engine.misra.checker --language rust src/main.rs
# or a whole crate:
python -m engine.misra.checker --language rust --project path/to/Cargo.toml
clippy is crate-based, so the target must live in a Cargo package (the backend
walks up to the enclosing Cargo.toml). Findings are surfaced under a single
rust-clippy standard with the lint name as the rule id (e.g.
clippy::needless_return). There is no MISRA/CERT for Rust; the value is the
clippy lint set plus the memory-safety guarantees the compiler enforces by
construction. ISO 26262 Table 6 mapping is intentionally sparse (Rust findings
show as unmapped rather than guessed). Requires cargo + the clippy
component (rustup component add clippy). Over the daemon, Rust is reached in
project mode ({"project": ".../Cargo.toml", "language": "rust"}), gated
behind the Pro rust_analysis feature. The browser-extension snippet flow does
not support Rust (clippy needs a crate); the daemon returns 422 for a Rust
snippet.
Free vs Pro
| Feature | Free | Pro |
|---|---|---|
| Single file analysis | Yes | Yes |
| AI fix suggestions | Yes | Yes |
| Batch analysis (multiple files) | No | Yes |
| PDF report export | No | Yes |
| Localized output (ko/de/ja/zh) | No | Yes |