forketyfork/zwanzig
GitHub: forketyfork/zwanzig
Zwanzig 是一个面向 Zig 语言的静态分析器和 linter,通过 AST 规则与基于 ZIR 的 CFG 驱动分析帮助开发者发现代码缺陷和风格问题。
Stars: 27 | Forks: 0
# zwanzig
[](https://github.com/forketyfork/zwanzig/actions/workflows/build.yml)
[](LICENSE)
[](https://ziglang.org/)
Zwanzig 是一个用于 Zig 代码的静态分析器和 linter,结合了快速的 AST/token 规则与基于 ZIR 输出的 CFG 驱动分析。
## 安装与使用
### 发布二进制文件
从[最新发布版本](https://github.com/forketyfork/zwanzig/releases/latest)下载适用于您平台的压缩包:
| 平台 | 压缩包 |
| --- | --- |
| Linux x86_64 | `zwanzig-vX.Y.Z-linux-x86_64.tar.gz` |
| macOS ARM64 | `zwanzig-vX.Y.Z-macos-aarch64.tar.gz` |
| Windows x86_64 | `zwanzig-vX.Y.Z-windows-x86_64.zip` |
解压压缩包,并将其目录添加到 `PATH` 中,或直接调用可执行文件:
```
./zwanzig src/
```
在 Windows 上,改为运行 `.\zwanzig.exe src\`。
### Zig 构建依赖
在您的 Zig 项目中将 Zwanzig 固定为依赖项。此命令会将依赖项 URL 和内容哈希添加到 `build.zig.zon` 中:
```
zig fetch --save=zwanzig https://github.com/forketyfork/zwanzig/archive/refs/tags/v0.14.0.tar.gz
```
在 `build.zig` 中添加一个 lint 步骤:
```
const zwanzig = b.dependency("zwanzig", .{
.target = b.graph.host,
.optimize = .ReleaseFast,
});
const run_zwanzig = b.addRunArtifact(zwanzig.artifact("zwanzig"));
run_zwanzig.addArgs(&.{"src"});
const lint_step = b.step("lint", "Run Zwanzig");
lint_step.dependOn(&run_zwanzig.step);
```
`b.graph.host` 会为运行构建的机器构建 Zwanzig,即使您的项目针对其他平台也是如此。`ReleaseFast` 避免了在 Debug 模式下运行分析器的巨大开销。
使用以下命令运行新步骤:
```
zig build lint
```
### GitHub Actions (SARIF)
在运行 Zwanzig 之前下载已固定版本的发布二进制文件。Linux runner 为 x86_64,因此使用 Linux x86_64 压缩包:
```
name: Zwanzig
on:
push:
pull_request:
permissions:
contents: read
security-events: write
env:
ZWANZIG_VERSION: v0.14.0
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install Zwanzig
run: |
archive="zwanzig-${ZWANZIG_VERSION}-linux-x86_64.tar.gz"
curl --fail --location --silent --show-error \
"https://github.com/forketyfork/zwanzig/releases/download/${ZWANZIG_VERSION}/${archive}" \
--output "${RUNNER_TEMP}/${archive}"
mkdir -p "${RUNNER_TEMP}/zwanzig"
tar -xzf "${RUNNER_TEMP}/${archive}" -C "${RUNNER_TEMP}/zwanzig"
echo "${RUNNER_TEMP}/zwanzig" >> "${GITHUB_PATH}"
- name: Run Zwanzig analysis
run: zwanzig --format sarif src/ > results.sarif || true
- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif
```
固定版本可保持 CI 的可重复性。当您想采用更新的发布版本时,请更新 `ZWANZIG_VERSION`。`|| true` 允许在 Zwanzig 报告诊断信息时运行 SARIF 上传。
## 功能
- 规则/检查器注册,带有共享的 `--do`/`--skip` 过滤
- 延迟解析,每个文件缓存 AST/token
- 通过 ZIR 进行类型感知分析
- 基于 CFG、路径敏感的检查器
- 用于 CFG、展开图和路径追踪的 Graphviz DOT 转储
- 跨文件并行分析
## 规则
AST/token 规则:
- dupe-import: 重复的 `@import` 语句
- todo: `// TODO` 注释
- file-as-struct: 基于类结构体顶级字段的文件命名
- unused-decl: 未使用的容器级声明
- unused-parameter: 未使用的函数参数
- unreachable-code: 无条件终止符或完全终止分支之后的代码
- empty-defer: 空的 `defer {}` 块
- empty-errdefer: 空的 `errdefer {}` 块
- shadowed-variable: 跨作用域的名称重用
- sentinel-alloc: 丢失 sentinel 类型的 sentinel 终止分配
- identifier-style: 类型/函数/值的命名约定
- deinit-lifecycle: `defer`/`errdefer` 周围有风险的清理/重新初始化生命周期模式
引擎支持的检查器:
- unreachable-code-engine: 常量条件的不可达代码
- optional-unwrap: 使用 `.?` 强制 optional 解包
- empty-catch-engine: 空的 `catch {}` 块
- swallowed-error: 忽略错误而未重新抛出或记录的 catch 块
- store-violations-engine: allocator/资源误用(double-free、泄漏、use-after-free/close)
- stack-escape-engine: 通过 return 或 async/thread 捕获而逃逸的栈-backed 值
- divide-by-zero-engine: 路径敏感的除/取模为零检测
- slice-bounds-engine: 数组/slice 越界访问检测
## 局限性
- ZIR/类型信息需要有效、可解析的 Zig 代码
- 完整的类型解析需要完整的构建上下文;独立分析的类型推断有限
- 嵌套作用域类型信息仍局限于模块级声明
- 过程间分析仅限于单个文件中的简单直接调用;跨文件调用被视为外部调用
- 增量缓存仅存储元数据;CFG 缓存已计划但尚未接入
## 文档
- 用法与 CLI:[docs/USAGE.md](docs/USAGE.md)
- 配置:[docs/CONFIG.md](docs/CONFIG.md)
- 输出格式:[docs/OUTPUT.md](docs/OUTPUT.md)
- CI 集成:[docs/CI.md](docs/CI.md)
- 内联抑制:[docs/SUPPRESSIONS.md](docs/SUPPRESSIONS.md)
- 开发说明:[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
- 规则与检查器详情:[docs/RULES.md](docs/RULES.md)
- 实现说明:[docs/IMPLEMENTATION.md](docs/IMPLEMENTATION.md)
- CFG/分析可视化:[docs/VISUALIZATION.md](docs/VISUALIZATION.md)
- 发布流程:[docs/RELEASE.md](docs/RELEASE.md)
- 示例配置:[docs/zwanzig.sample.json](docs/zwanzig.sample.json)
## 许可证
MIT
标签:Apache Flink, SOC Prime, Zig, 云安全监控, 代码规范检查, 开发工具, 静态分析