一、Coverity 测试工具介绍
1.1 基础定义
Coverity 是新思科技(Synopsys Black Duck)旗下商用SAST静态源代码分析工具,源自斯坦福大学学术成果,无需运行程序,仅扫描源码即可提前挖掘代码缺陷、安全漏洞、编码合规问题,是航空、汽车、军工、嵌入式高安全领域主流代码测试工具。
简单理解:代码静态“CT体检仪”,属于白盒静态测试,不编译运行程序,就能发现运行期才会暴露的隐性Bug。
1.2 核心工作原理
- 源码解析:读取源码,构建抽象语法树AST、控制流图CFG;
- 跨函数数据流/污点传播分析:全局追踪变量、外部不可信输入(污点数据)全链路流转;
- 路径敏感符号执行:模拟所有分支、循环、异常执行路径,普通简单扫描工具仅做正则匹配,Coverity 支持深度跨文件、跨函数分析;
- 规则匹配:内置数千条检测规则,匹配缺陷并生成完整问题链路证据;
- 缺陷分级+报告输出:区分误报,给出代码行、根因、修复方案。
1.3 支持编程语言与场景
1.3.1 支持语言
支持22+种编程语言,C/C++ 为核心优势,同时包含 Java、C#、Python、JS/TS、Go、Swift、Kotlin、PHP、Objective-C、Ruby 等。
1.3.2 核心适用行业
军工/航电(DO-178C)、汽车电子(ISO 26262、MISRA)、工业控制、医疗设备、金融高安全系统、大型后端、嵌入式底层系统。
1.4 三大核心检测能力
1.4.1 运行时致命代码缺陷(嵌入式重点)
内存类:内存泄漏、缓冲区溢出、数组越界、野指针、空指针解引用、未初始化变量;
资源类:文件句柄/套接字/数据库连接未释放;
并发类:死锁、多线程数据竞争;
运算类:整数溢出、符号转换错误、除零风险;
逻辑类:死代码、函数返回值未校验、拷贝错误等。
1.4.2 网络安全漏洞
覆盖 OWASP Top10、CWE 标准,可检测 SQL注入、XSS跨站、硬编码密钥、不安全反序列化、路径遍历等高危漏洞。
1.4.3 行业编码合规检查
原生支持 MISRA C/C++、CERT C/C++、DO-178、ISO 2626、国军标等行业编码规范,可自定义拓展行业规则。
1.5 工具组成模块
- cov-analyze 扫描引擎:核心分析程序,对接 Make/CMake/Keil 等编译工具;
- Coverity Connect:Web管理平台,用于项目管理、缺陷流转、审计、报表导出;
- Code Sight IDE插件:VS Code/Eclipse/VS 实时编码检测;
- CI/CD集成插件:Jenkins/GitLab 流水线自动扫描、门禁拦截。
1.6 核心优势 & 对比
1.6.1 核心优势
- 极低误报率,深度数据流分析优于普通正则扫描工具;
- C/C++ 嵌入式分析能力行业顶尖;
- 完整缺陷追溯、基线、审计能力,适配军工/车载合规要求;
- 支持增量扫描,大型代码库效率高;
- 支持私有化离线部署,适配涉密场景。
1.6.2 同类工具区分
- Coverity:主打嵌入式、军工、汽车,侧重内存/并发/国军标合规;
- SonarQube:开源为主,侧重代码风格、Web漏洞,嵌入式能力弱;
- Klocwork:同嵌入式赛道,汽车领域使用较多;
- Fortify:Web安全漏洞更强,底层C/C++分析偏弱。
1.7 工具局限
- 必须捕获完整编译过程,无法直接扫描零散源码;
- 商业收费,无完整免费版本;
- 交叉编译场景需要额外适配编译器。
二、GJB8114-2013 《C/C++语言编程安全子集》标准概述
2.1 标准基础信息
- 标准编号:GJB 8114-2013
- 发布时间:2013-07-10,实施时间:2013-10-01
- 适用范围:军用安全关键C/C++软件,其他军用软件可参照执行
- 规则分类:强制准则(必须遵守)、建议准则(推荐遵守)
2.2 标准整体结构
- 通用部分:范围、引用文件、术语、总则;
- C/C++ 共用准则(5大模块):声明定义、版面书写、指针、分支、跳转、运算、函数、循环、类型转换、初始化、比较、变量等;
- C++ 专用准则:类、构造/析构、虚函数、类型转换、内存、异常、模板等;
- 评价规范:缺陷统计、违背率计算、等级划分;
- 附录:规则索引、评价示例。
2.3 评价规则(核心审计要求)
2.3.1 计算公式
- N:软件总语句行数
- L:所有强制准则违背总行数
- 违背率 P=NL×1000‰
2.3.2 评价等级
| 违背率范围 |
评价结论 |
| P≤3‰ |
非常好 |
| 3‰<P≤20‰ |
好 |
| 20‰<P≤40‰ |
较好 |
| 40‰<P≤60‰ |
较差 |
| 60‰<P≤100‰ |
差 |
| P>100‰ |
非常差 |
各项目可根据实际需求微调区间。
三、Coverity 与 GJB8114-2013 融合落地方案
Coverity 无官方预置GJB8114规则包,依托自定义规则、编译适配、平台管控、流水线集成能力,实现国军标全量落地,构建「缺陷检测+国军标合规」一体化体系。
3.1 规则能力分层匹配
3.1.1 原生复用(无需开发)
GJB8114大量规则与 Coverity 内置 MISRA / CERT 规则重合,直接启用:
指针、内存、数组越界、除零、函数签名、头文件保护、gets禁用、内存泄漏等。
3.1.2 配置开关(简单适配)
修改工具阈值/开关即可实现:
代码行数限制、函数行数限制、分支嵌套层数、无限循环管控、注释规范等。
3.1.3 自定义规则(军工特有)
GJB8114独有规则,需基于 Coverity 编码标准/自定义检查器开发:
宏管控、位域规则、变量命名、switch严格规范、C++菱形继承/异常规则等。
3.2 步骤1:搭建 GJB8114 专属规则集
3.2.1 规则文件路径
Coverity 规则根目录:$COVERITY_HOME/config/coding-standards/
- 复制现有标准模板(如
misrac2012),重命名为gjb8114_2013;
- 核心文件:
config.xml:规则总开关、告警等级;
rules/:单条规则定义;
messages/:告警文案(绑定GJB8114编号+原文)。
3.2.2 规则开发规范
- 规则ID命名:
gjb8114_规则编号(例:gjb8114_R_1_1_1);
- 等级划分:强制准则=Error(阻断)、建议准则=Warning(提醒);
- 告警内容:必须标注GJB8114准则编号、规则原文;
- 测试要求:基于标准内「违背/遵循示例」完成漏报、误报验证,输出工具能力确认报告。
3.2.3 简易规则示例
<rule id="gjb8114_R_1_9_4" severity="error" category="GJB8114-循环控制">
<description>GJB8114 R-1-9-4:无限循环必须使用while(1),禁止for(;;)</description>
<pattern>for\s*\(\s*;\s*\)</pattern>
<message>违背GJB8114强制准则R-1-9-4:禁用for(;;),请使用while(1)</message>
</rule>
3.3 步骤2:扫描编译配置(嵌入式/交叉编译适配)
3.3.1 标准扫描命令
cov-build --dir cov-int make
cov-analyze --dir cov-int --coding-standard gjb8114_2013 --enable-all --timeout 3600
cov-commit-defects --dir cov-int --host 内网地址 --stream 项目名
3.3.2 嵌入式专项配置
- 指定交叉编译器:
cov-configure --compiler arm-linux-gcc;
- 拦截头文件绝对路径;
- 关闭编译器非标准扩展,适配位域、结构体对齐规则。
3.4 步骤3:Coverity Connect 平台适配
- 项目规划:按型号/模块创建独立Stream,绑定GJB8114规则集;
- 自定义字段:新增「GJB8114规则编号、规则类型、违背行数、整改状态」;
- 基线&豁免:存量问题纳入基线,强制准则豁免必须附审批单;
- 权限管控:按角色分配权限(开发/测试/管理员),适配涉密要求。
3.5 步骤4:CI/CD 流水线自动化门禁
3.5.1 流水线流程
代码提交 → 编译构建 → Coverity增量扫描 → 合规门禁 → 代码合入
3.5.2 门禁策略
- 强制准则(Error):直接阻断代码合入;
- 建议准则(Warning):仅记录,限期整改;
- 禁止新增基线外违规项。
3.5.3 Jenkins 脚本示例
stage('GJB8114 代码合规检测') {
steps {
sh 'cov-build --dir cov-int make'
sh 'cov-analyze --dir cov-int --coding-standard gjb8114_2013'
script {
def errorNum = sh(script: 'cov-format-errors --dir cov-int | grep "GJB8114-R" | wc -l', returnStdout).toInteger()
if(errorNum > 0) {
error "代码违背GJB8114强制准则,禁止合入!"
}
}
}
}
3.6 步骤5:统计评价与报表输出
- 从Coverity导出CSV/Excel报告,提取总行数N、违背行数L;
- 计算违背率,对照标准生成评价结论;
- 标准交付报表:基础信息、违规清单、统计结果、附件(日志/审批单)。
3.7 步骤6:IDE 本地检测
部署 Coverity Code Sight 插件(VS Code/Eclipse),本地编码时实时提示GJB8114违规,提前整改。
3.8 分阶段落地计划
- 试点阶段(1-2周):选取小模块,完成规则开发、用例测试;
- 集成阶段(2-3周):平台配置+流水线接入,全员培训;
- 常态化运维(长期):全项目推广,按月输出合规报告,定期迭代规则。
3.9 常见问题优化
- 误报/漏报:补充测试用例,特殊场景配置审批白名单;
- 扫描缓慢:开启增量扫描、模块并行分析;
- 涉密环境:全内网离线部署,数据本地存储备份。
四、GJB8114-2013 与 Coverity 完整规则映射表
说明
- 适配类型:
原生复用/配置开关/自定义规则
- 级别:
强制(R)=Error、建议(A)=Warning
4.1 C/C++ 共用准则
4.1.1 5.1 声明定义(R-1-1 / A-1-1 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-1-1 |
禁止宏改变关键字、基本类型含义 |
强制 |
自定义规则 |
正则/AST匹配#define目标为int/long/char等关键字 |
| R-1-1-2 |
禁止宏定义为关键字/基本类型 |
强制 |
自定义规则 |
检测#define 别名 关键字场景 |
| R-1-1-3 |
typedef 类型禁止重定义 |
强制 |
原生复用 |
启用MISRA类型重定义检查 |
| R-1-1-4 |
禁止重新定义C/C++关键字 |
强制 |
自定义规则 |
检测标识符与关键字重名 |
| R-1-1-5 |
#define 禁止重复定义 |
强制 |
原生复用 |
启用预处理重复宏检查,保留#undef后重定义豁免 |
| R-1-1-6 |
函数内#define / #undef 必须配对 |
强制 |
自定义规则 |
函数作用域内宏成对校验 |
| R-1-1-7 |
函数式宏参数、结果必须加括号 |
强制 |
原生复用 |
启用CERT宏安全规则 |
| R-1-1-8 |
结构体/联合/枚举必须定义标识名 |
强制 |
自定义规则 |
AST检测无名struct/union/enum |
| R-1-1-9 |
结构体禁止嵌套无名结构体 |
强制 |
自定义规则 |
递归检测内部无名子结构 |
| R-1-1-10 |
有符号位域位长必须>1 |
强制 |
自定义规则 |
拦截signed 类型 : 1 |
| R-1-1-11 |
位域必须显式指定有/无符号 |
强制 |
原生复用 |
启用MISRA位域规则 |
| R-1-1-12 |
位域类型统一、不跨类型长度 |
强制 |
自定义规则 |
校验位域基础类型与位总长 |
| R-1-1-13 |
函数声明必须带参数类型+变量名 |
强制 |
原生复用 |
启用严格函数原型检查 |
| R-1-1-14 |
函数声明与原型完全一致 |
强制 |
原生复用 |
函数签名全量校验 |
| R-1-1-15 |
函数形参必须显式声明类型 |
强制 |
原生复用 |
禁用K&R旧式函数定义 |
| R-1-1-16 |
外部变量声明与定义类型一致 |
强制 |
原生复用 |
跨文件变量类型校验 |
| R-1-1-17 |
禁止函数体内写extern声明 |
强制 |
自定义规则 |
检测函数内部extern语句 |
| R-1-1-18 |
数组必须显式指定长度 |
强制 |
自定义规则 |
拦截int arr[]无界数组定义 |
| R-1-1-19 |
extern 变量禁止初始化 |
强制 |
原生复用 |
外部变量初始化检查 |
| R-1-1-20 |
数值用char必须显式有/无符号 |
强制 |
原生复用 |
启用CERT char符号检查 |
| R-1-1-21 |
#include 禁止使用绝对路径 |
强制 |
自定义规则 |
正则拦截盘符绝对路径 |
| R-1-1-22 |
禁止头文件重复包含 |
强制 |
原生复用 |
头文件保护检查 |
| R-1-1-23 |
空参数函数必须写 void |
强制 |
原生复用 |
禁用fun(),强制fun(void) |
| A-1-1-1 |
建议用typedef封装基础类型 |
建议 |
配置开关 |
统计原生基础类型使用量 |
| A-1-1-2 |
谨慎宏括号不匹配 |
建议 |
原生复用 |
宏语法告警增强 |
| A-1-1-3 |
谨慎使用#、##宏运算符 |
建议 |
配置开关 |
宏拼接/字符串化告警 |
| A-1-1-4 |
函数变量统一在头部定义 |
建议 |
配置开关 |
检测行内变量定义 |
| A-1-1-5 |
结构体嵌套不超3层 |
建议 |
配置开关 |
嵌套层数阈值=3 |
| A-1-1-6 |
建议宏/const定义常量 |
建议 |
配置开关 |
魔法数字告警 |
4.1.2 5.2 版面书写(R-1-2 / A-1-2 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-2-1 |
循环体必须加大括号 |
强制 |
配置开关 |
强制for/while单语句带{} |
| R-1-2-2 |
if/else if/else 必须加大括号 |
强制 |
配置开关 |
强制分支单语句带{} |
| R-1-2-3 |
头文件前禁止可执行代码 |
强制 |
自定义规则 |
检测#include之前存在执行语句 |
| R-1-2-4 |
歧义逻辑表达式必须加括号 |
强制 |
原生复用 |
运算符优先级告警 |
| R-1-2-5 |
位运算、逻辑运算项必须加括号 |
强制 |
原生复用 |
混合运算括号检查 |
| R-1-2-6 |
禁止嵌套注释 |
强制 |
原生复用 |
注释语法检查 |
| A-1-2-1 |
单文件语句≤2000行 |
建议 |
配置开关 |
文件行数阈值=2000 |
| A-1-2-2 |
单函数语句≤200行 |
建议 |
配置开关 |
函数行数阈值=200 |
| A-1-2-3 |
C谨慎使用//注释 |
建议 |
配置开关 |
C文件//注释告警 |
4.1.3 5.3 指针使用(R-1-3 / A-1-3 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-3-1 |
指针级数不超过两级(***禁用) |
强制 |
自定义规则 |
统计指针层级,拦截三级及以上 |
| R-1-3-2 |
函数指针取值必须加& |
强制 |
自定义规则 |
函数指针赋值缺少&告警 |
| R-1-3-3 |
禁止对入参指针直接赋值 |
强制 |
自定义规则 |
函数内修改形参指针地址 |
| R-1-3-4 |
禁止返回局部变量地址 |
强制 |
原生复用 |
高危内存检查 |
| R-1-3-5 |
禁止使用/重复释放野指针 |
强制 |
原生复用 |
野指针、重复free检查 |
| R-1-3-6 |
指针free后必须置NULL |
强制 |
自定义规则 |
free后未赋值NULL告警 |
| R-1-3-7 |
动态指针定义时初始化为NULL |
强制 |
自定义规则 |
未初始化动态指针告警 |
| R-1-3-8 |
动态指针使用前判NULL |
强制 |
原生复用 |
空指针解引用前置检查 |
| R-1-3-9 |
空指针统一使用NULL,不用0 |
强制 |
自定义规则 |
拦截指针判断==0/!=0 |
| R-1-3-10 |
文件指针使用完毕必须fclose |
强制 |
原生复用 |
文件句柄泄漏检查 |
| A-1-3-1 |
谨慎使用函数指针 |
建议 |
配置开关 |
函数指针使用告警 |
| A-1-3-2 |
谨慎使用void*无类型指针 |
建议 |
原生复用 |
通用指针告警 |
| A-1-3-3 |
谨慎指针算术运算 |
建议 |
配置开关 |
指针加减运算告警 |
4.1.4 5.4 分支控制(R-1-4 / A-1-4 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-4-1 |
if-else if 链必须补else |
强制 |
自定义规则 |
分支完整性检查 |
| R-1-4-2 |
空分支必须写;/* no deal with */ |
强制 |
自定义规则 |
空语句+固定注释校验 |
| R-1-4-3 |
禁止空switch语句 |
强制 |
自定义规则 |
拦截switch(){} |
| R-1-4-4 |
禁止对bool量使用switch |
强制 |
自定义规则 |
switch表达式为布尔值告警 |
| R-1-4-5 |
switch 不能只有default |
强制 |
自定义规则 |
仅含default的switch告警 |
| R-1-4-6 |
switch 除完整枚举外必须有default |
强制 |
原生复用 |
switch完整性检查 |
| R-1-4-7 |
case/default 必须break/return;共用case加注释 |
强制 |
原生复用 |
switch穿透检查,补充注释校验 |
| R-1-4-8 |
switch 分支层级统一,禁止内嵌case |
强制 |
自定义规则 |
检测if内部嵌套case |
| A-1-4-1 |
分支嵌套最多7层 |
建议 |
配置开关 |
嵌套层数阈值=7 |
4.1.5 5.5 跳转控制(R-1-5 / A-1-5 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-5-1 |
禁止跨复合语句、向上goto |
强制 |
自定义规则 |
作用域+数据流分析管控goto |
| R-1-5-2 |
禁止使用setjmp/longjmp |
强制 |
原生复用 |
直接拦截函数调用 |
| A-1-5-1 |
谨慎使用goto |
建议 |
配置开关 |
goto通用告警 |
4.1.6 5.6 运算处理(R-1-6 / A-1-6 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-6-1 |
浮点常数禁止直接赋给整型 |
强制 |
原生复用 |
隐式浮点转整型检查 |
| R-1-6-2 |
禁止赋值越界整数 |
强制 |
原生复用 |
数值溢出检查 |
| R-1-6-3 |
逻辑表达式内禁止赋值 |
强制 |
原生复用 |
拦截if(a=b)写法 |
| R-1-6-4 |
逻辑量禁止做位运算 |
强制 |
自定义规则 |
逻辑表达式执行位运算告警 |
| R-1-6-5 |
表达式/函数参数禁止使用++/– |
强制 |
自定义规则 |
复合表达式内自增自减拦截 |
| R-1-6-6 |
移位位数不超过变量位长 |
强制 |
原生复用 |
移位溢出检查 |
| R-1-6-7 |
移位位数不能为负数 |
强制 |
原生复用 |
移位操作数符号检查 |
| R-1-6-8 |
数组禁止越界访问 |
强制 |
原生复用 |
数组/缓冲区越界检查 |
| R-1-6-9 |
数组下标≥0 |
强制 |
原生复用 |
负数下标拦截 |
| R-1-6-10 |
禁止对常量做!逻辑非 |
强制 |
自定义规则 |
拦截!1 / !0 |
| R-1-6-11 |
非枚举变量禁止使用枚举值 |
强制 |
自定义规则 |
枚举类型匹配校验 |
| R-1-6-12 |
禁止除零、取模零 |
强制 |
原生复用 |
除零风险检测 |
| R-1-6-13 |
sizeof 内部禁止赋值 |
强制 |
自定义规则 |
拦截sizeof(赋值表达式) |
| R-1-6-14 |
缓冲区读取不越界 |
强制 |
原生复用 |
memcpy等读取长度检查 |
| R-1-6-15 |
缓冲区写入不越界 |
强制 |
原生复用 |
memcpy等写入长度检查 |
| R-1-6-16 |
禁止使用已释放内存 |
强制 |
原生复用 |
悬挂指针检查 |
| R-1-6-17 |
free 必须使用原始指针 |
强制 |
自定义规则 |
指针偏移后free告警 |
| R-1-6-18 |
禁用gets,强制fgets |
强制 |
原生复用 |
直接拦截gets调用 |
| R-1-6-19 |
字符串拷贝/追加目标不越界 |
强制 |
原生复用 |
strncpy/strncat长度校验 |
| A-1-6-1 |
谨慎有符号数位运算 |
建议 |
配置开关 |
有符号数位运算告警 |
| A-1-6-2 |
谨慎整型除法 |
建议 |
配置开关 |
整除风险告警 |
| A-1-6-3 |
动态内存及时释放 |
建议 |
原生复用 |
内存泄漏增强检查 |
| A-1-6-4 |
建议用strncpy替代strcpy |
建议 |
配置开关 |
strcpy调用告警 |
| A-1-6-5 |
建议用strncat替代strcat |
建议 |
配置开关 |
strcat调用告警 |
| A-1-6-6 |
谨慎逗号运算符 |
建议 |
配置开关 |
逗号表达式告警 |
4.1.7 5.7 函数调用(R-1-7 / A-1-7 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-7-1 |
禁止重写标准库函数 |
强制 |
原生复用 |
标准函数重定义检查 |
| R-1-7-2 |
实参与形参类型一致 |
强制 |
原生复用 |
参数类型匹配 |
| R-1-7-3 |
实参、形参个数一致 |
强制 |
原生复用 |
参数个数校验 |
| R-1-7-4 |
禁用旧式K&R函数定义 |
强制 |
原生复用 |
旧式语法拦截 |
| R-1-7-5 |
声明与定义参数类型一致 |
强制 |
原生复用 |
跨文件函数签名校验 |
| R-1-7-6 |
声明与定义返回值一致 |
强制 |
原生复用 |
返回值类型校验 |
| R-1-7-7 |
有返回值函数必须return |
强制 |
原生复用 |
缺失返回语句检查 |
| R-1-7-8 |
无返回值函数return不带值 |
强制 |
原生复用 |
void函数返回值拦截 |
| R-1-7-9 |
有返回值return必须带值 |
强制 |
原生复用 |
空return拦截 |
| R-1-7-10 |
返回值类型与定义匹配 |
强制 |
原生复用 |
返回值类型校验 |
| R-1-7-11 |
弃用返回值必须加(void) |
强制 |
自定义规则 |
无(void)丢弃返回值告警 |
| R-1-7-12 |
void函数调用禁止加(void) |
强制 |
自定义规则 |
多余(void)拦截 |
| R-1-7-13 |
静态函数必须被调用 |
强制 |
原生复用 |
未使用静态函数检查 |
| R-1-7-14 |
同一表达式不调用顺序相关函数 |
强制 |
自定义规则 |
多副作用函数同表达式告警 |
| R-1-7-15 |
函数参数禁止使用省略号… |
强制 |
自定义规则 |
拦截可变参数列表 |
| R-1-7-16 |
禁止直接/间接递归 |
强制 |
原生复用 |
递归调用检测 |
| A-1-7-1 |
函数参数≤10个 |
建议 |
配置开关 |
参数个数阈值=10 |
| A-1-7-2 |
避免未使用参数 |
建议 |
原生复用 |
无用形参检查 |
| A-1-7-3 |
谨慎使用abort/exit |
建议 |
配置开关 |
进程退出函数告警 |
| A-1-7-4 |
系统函数校验返回值 |
建议 |
原生复用 |
返回值未判断告警 |
| A-1-7-5 |
数组传参建议同步传长度 |
建议 |
配置开关 |
数组无长度告警 |
4.1.8 5.8 语句使用(R-1-8 / A-1-8 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-8-1 |
禁止不可达语句 |
强制 |
原生复用 |
死代码检测 |
| R-1-8-2 |
禁止不可达分支 |
强制 |
原生复用 |
永真/永假分支检测 |
| R-1-8-3 |
禁止无效语句 |
强制 |
自定义规则 |
无意义表达式告警 |
| R-1-8-4 |
八进制常量必须加/octal/注释 |
强制 |
自定义规则 |
八进制数注释校验 |
| R-1-8-5 |
数值后缀统一使用大写 |
强制 |
自定义规则 |
拦截u/l/f小写后缀 |
| A-1-8-1 |
避免空语句 |
建议 |
配置开关 |
单独分号告警 |
| A-1-8-2 |
避免无用变量 |
建议 |
原生复用 |
未使用变量检查 |
| A-1-8-3 |
避免无用函数 |
建议 |
原生复用 |
未使用函数检查 |
| A-1-8-4 |
推荐使用大写数值后缀 |
建议 |
同R-1-8-5 |
|
4.1.9 5.9 循环控制(R-1-9 / A-1-9 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-9-1 |
for循环变量必须是局部变量 |
强制 |
自定义规则 |
全局/静态循环变量告警 |
| R-1-9-2 |
for循环变量必须为整型 |
强制 |
自定义规则 |
浮点循环变量拦截 |
| R-1-9-3 |
循环体内禁止修改循环变量 |
强制 |
自定义规则 |
循环内修改控制变量告警 |
| R-1-9-4 |
无限循环仅允许while(1),禁用for(;;) |
强制 |
自定义规则 |
拦截for(;;) |
| A-1-9-1 |
谨慎使用无限循环 |
建议 |
配置开关 |
while(1)告警 |
| A-1-9-2 |
循环内少用break |
建议 |
配置开关 |
多break告警 |
| A-1-9-3 |
循环内少用continue |
建议 |
配置开关 |
多continue告警 |
4.1.10 5.10 类型转换(R-1-10 / A-1-10 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-10-1 |
浮点转整型必须强转 |
强制 |
原生复用 |
隐式转换拦截 |
| R-1-10-2 |
长整型转短整型必须强转 |
强制 |
原生复用 |
不同长度整型隐式转换拦截 |
| R-1-10-3 |
double转float必须强转 |
强制 |
原生复用 |
双精度转单精度隐式转换拦截 |
| R-1-10-4 |
指针赋值类型必须一致 |
强制 |
原生复用 |
指针类型不匹配检查 |
| R-1-10-5 |
指针与普通变量互转必须强转 |
强制 |
原生复用 |
地址/数值隐式互转拦截 |
| R-1-10-6 |
禁止无意义多层强转 |
强制 |
自定义规则 |
冗余转换告警 |
| A-1-10-1 |
浮点转整型考虑四舍五入 |
建议 |
配置开关 |
浮点截断告警 |
| A-1-10-2 |
谨慎double转float |
建议 |
原生复用 |
精度丢失告警 |
| A-1-10-3 |
谨慎长整型转短整型 |
建议 |
原生复用 |
数据截断告警 |
| A-1-10-4 |
谨慎指针与数值互转 |
建议 |
原生复用 |
地址转换告警 |
4.1.11 5.11 初始化(R-1-11 / A-1-11 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-11-1 |
变量使用前必须赋值 |
强制 |
原生复用 |
未初始化变量检查 |
| R-1-11-2 |
不依赖系统默认初始化 |
强制 |
自定义规则 |
全局/静态变量手动初始化校验 |
| R-1-11-3 |
嵌套结构体初始化格式匹配 |
强制 |
自定义规则 |
初始化花括号层级校验 |
| R-1-11-4 |
枚举初始化完整 |
强制 |
自定义规则 |
枚举元素初始化规则校验 |
| A-1-11-1 |
声明同时初始化变量 |
建议 |
配置开关 |
声明赋值分离告警 |
| A-1-11-2 |
全局变量统一模块初始化 |
建议 |
配置开关 |
分散初始化告警 |
4.1.12 5.12 比较判断(R-1-12 / A-1-12 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-12-1 |
逻辑量禁止> / <比较 |
强制 |
自定义规则 |
布尔值大小比较拦截 |
| R-1-12-2 |
指针禁止> / <比较 |
强制 |
原生复用 |
指针大小比较告警 |
| R-1-12-3 |
浮点数禁止== / !=判断 |
强制 |
原生复用 |
浮点等值判断拦截 |
| R-1-12-4 |
无符号数禁止判正负 |
强制 |
自定义规则 |
拦截unsigned x >=0 / x <0 |
| R-1-12-5 |
有/无符号数禁止直接比较 |
强制 |
原生复用 |
混合符号比较告警 |
| A-1-12-1 |
常量写在比较符左侧 |
建议 |
配置开关 |
变量==常量写法告警 |
4.1.13 5.13 变量使用(R-1-13 / A-1-13 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-1-13-1 |
局部变量不与全局重名 |
强制 |
自定义规则 |
作用域变量重名检查 |
| R-1-13-2 |
形参不与全局重名 |
强制 |
自定义规则 |
形参/全局变量重名 |
| R-1-13-3 |
变量名不与函数名重名 |
强制 |
自定义规则 |
标识符重名校验 |
| R-1-13-4 |
变量名不与结构体/联合体名重名 |
强制 |
自定义规则 |
类型名与变量重名 |
| R-1-13-5 |
变量名不与枚举元素重名 |
强制 |
自定义规则 |
枚举项与变量重名 |
| R-1-13-6 |
变量名不与typedef类型重名 |
强制 |
自定义规则 |
自定义类型与变量重名 |
| R-1-13-7 |
代码块内不重定义外层变量 |
强制 |
自定义规则 |
变量遮蔽告警 |
| R-1-13-8 |
不依靠大小写区分变量 |
强制 |
自定义规则 |
近似大小写变量告警 |
| R-1-13-9 |
不区分 l/1 命名变量 |
强制 |
自定义规则 |
l与数字1混淆命名拦截 |
| R-1-13-10 |
不区分 O/0 命名变量 |
强制 |
自定义规则 |
O与数字0混淆命名拦截 |
| R-1-13-11 |
禁止单独用 l / O 作为变量名 |
强制 |
自定义规则 |
单字符l/O变量拦截 |
| R-1-13-12 |
外部可修改变量加volatile |
强制 |
原生复用 |
共享/寄存器变量校验 |
| R-1-13-13 |
表达式不重复使用同一volatile |
强制 |
自定义规则 |
多次读取volatile告警 |
| R-1-13-14 |
NULL 不当作整型0使用 |
强制 |
自定义规则 |
NULL作为数字传参拦截 |
| R-1-13-15 |
无符号变量禁止赋负值 |
强制 |
原生复用 |
负值赋值给unsigned拦截 |
| R-1-13-16 |
字符串数组必须以\0结尾 |
强制 |
原生复用 |
字符串结束符检查 |
| A-1-13-1 |
推荐类型前缀命名 |
建议 |
配置开关 |
命名规范度量告警 |
| A-1-13-2 |
谨慎使用register变量 |
建议 |
配置开关 |
register关键字告警 |
4.2 C++ 专用准则
4.2.1 6.1 类与对象(R-2-1 / A-2-1 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-1-1 |
含动态成员的类必须实现拷贝构造、赋值重载 |
强制 |
自定义检查器 |
AST分析动态成员与拷贝函数 |
| R-2-1-2 |
虚基类转派生类必须用dynamic_cast |
强制 |
原生复用 |
C++类型转换规则增强 |
| R-2-1-3 |
菱形继承基类必须virtual |
强制 |
自定义检查器 |
菱形继承结构校验 |
| R-2-1-4 |
抽象类拷贝运算符设为protected/private |
强制 |
自定义检查器 |
抽象类权限检查 |
| A-2-1-1 |
谨慎虚基类派生 |
建议 |
配置开关 |
virtual基类告警 |
| A-2-1-2 |
谨慎内联函数 |
建议 |
配置开关 |
复杂inline函数告警 |
4.2.2 6.2 构造函数(R-2-2 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-2-1 |
构造函数禁止使用全局变量 |
强制 |
自定义检查器 |
构造内读写全局变量告警 |
| R-2-2-2 |
类必须显式定义默认构造函数 |
强制 |
自定义检查器 |
无默认构造告警 |
| R-2-2-3 |
单参数构造必须加explicit |
强制 |
原生复用 |
隐式转换构造拦截 |
| R-2-2-4 |
构造函数初始化全部成员 |
强制 |
原生复用 |
成员未初始化检查 |
| R-2-2-5 |
派生类构造必须调用直接基类构造 |
强制 |
原生复用 |
继承构造完整性检查 |
4.2.3 6.3 析构函数(R-2-3 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-3-1 |
含虚函数的类,析构必须virtual |
强制 |
原生复用 |
C++经典安全规则 |
| R-2-3-2 |
析构函数异常必须内部捕获 |
强制 |
自定义检查器 |
析构抛出未捕获异常告警 |
4.2.4 6.4 虚拟函数(R-2-4 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-4-1 |
重写虚函数不修改默认参数 |
强制 |
自定义检查器 |
缺省参数一致性校验 |
| R-2-4-2 |
重写虚函数必须显式virtual |
强制 |
自定义检查器 |
缺失virtual告警 |
| R-2-4-3 |
非纯虚函数不能被重写为纯虚 |
强制 |
自定义检查器 |
虚函数降级拦截 |
4.2.5 6.5 类型转换(R-2-5 / A-2-5 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-5-1 |
无关类型指针禁止强转为对象指针 |
强制 |
原生复用 |
危险指针转换检查 |
| R-2-5-2 |
转换禁止去除const/volatile |
强制 |
原生复用 |
常量属性移除拦截 |
| A-2-5-1 |
推荐使用C++风格转换 |
建议 |
配置开关 |
C风格强转告警 |
4.2.6 6.6 内存释放(R-2-6 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-6-1 |
new 必须配对 delete |
强制 |
原生复用 |
内存配对检查 |
| R-2-6-2 |
new[] 必须配对 delete[] |
强制 |
原生复用 |
数组内存释放匹配 |
| R-2-6-3 |
delete 必须使用原始指针 |
强制 |
自定义检查器 |
指针偏移后delete告警 |
4.2.7 6.7 函数定义与使用(R-2-7 / A-2-7 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-7-1 |
定长数组传参使用引用 |
强制 |
自定义检查器 |
数组退化指针拦截 |
| R-2-7-2 |
const成员函数不返回非const指针/引用 |
强制 |
原生复用 |
const权限检查 |
| R-2-7-3 |
禁止外部修改私有成员 |
强制 |
自定义检查器 |
成员外泄告警 |
| A-2-7-1 |
类内不写函数实现 |
建议 |
配置开关 |
类内函数实现告警 |
| A-2-7-2 |
非修改指针/引用参数加const |
建议 |
配置开关 |
可const参数未修饰告警 |
4.2.8 6.8 异常处理(R-2-8 / A-2-8 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-8-1 |
异常捕获:派生类在前、基类在后 |
强制 |
自定义检查器 |
catch顺序校验 |
| R-2-8-2 |
每一种throw都要有对应catch |
强制 |
原生复用 |
未捕获异常检查 |
| R-2-8-3 |
异常必须引用方式捕获 |
强制 |
自定义检查器 |
值/指针捕获拦截 |
| R-2-8-4 |
默认捕获catch(…)放在最后 |
强制 |
自定义检查器 |
默认捕获顺序校验 |
| R-2-8-5 |
禁止直接throw NULL |
强制 |
自定义检查器 |
throw NULL拦截 |
| A-2-8-1 |
建议增加默认捕获兜底 |
建议 |
配置开关 |
无默认捕获告警 |
| A-2-8-2 |
谨慎抛出/捕获指针异常 |
建议 |
配置开关 |
指针异常告警 |
4.2.9 6.9 其他条款(R-2-9 / A-2-9 系列)
| 准则编号 |
规则内容 |
级别 |
适配类型 |
实现要点 & Coverity配置 |
| R-2-9-1 |
模板声明、定义、实现同文件 |
强制 |
自定义检查器 |
模板代码分离告警 |
| A-2-9-1 |
模板参数使用typename |
建议 |
配置开关 |
模板关键字校验 |
| A-2-9-2 |
const 修饰放类型最左侧 |
建议 |
配置开关 |
const书写风格告警 |
| A-2-9-3 |
不重载&&、||、逗号运算符 |
建议 |
配置开关 |
运算符重载告警 |
| A-2-9-4 |
禁用旧式.h标准头文件 |
建议 |
配置开关 |
iostream.h等旧式头文件告警 |
五、补充说明
- 落地优先级:优先「原生复用+配置开关」规则,再分批开发自定义规则;
- 合规校验:所有规则必须使用标准内「违背/遵循示例」完成漏报、误报测试;
- 报表适配:将GJB8114规则编号作为Coverity自定义字段,直接用于违背率计算与审计;
- 告警统一规范:强制准则=Error(门禁阻断),建议准则=Warning(仅记录)。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)