ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CodeQL C++ 库 1.4.0 变更详解:模板推导指南、explicit 检测与 using enum 建模增强

CodeQL C++ 库 1.4.0 变更详解:模板推导指南、explicit 检测与 using enum 建模增强 静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载本篇文章系统梳理 CodeQL 仓库中 C 分析库cpp/ql/lib1.4.0 版本发布的新特性与静态分析改进涵盖DeductionGuide、Function、NewOrNewArrayExpr/DeleteOrDeleteArrayExpr等核心 QL 类新增的谓词以及constexpr if未求值语义、别名分析性能与using enum声明建模的调整。读者将掌握这些新增 QL API 的调用方式、底层数据表支撑与典型查询场景可直接用于编写或扩展 C 安全与质量分析查询。一、版本概览与适用范围CodeQL C 分析库的 1.4.0 版本变更记录位于 cpp/ql/lib/change-notes/released/1.4.0.md该版本主要面向 C 语言建模层的能力增强包含四类新增 QL 谓词与三项语义/性能改进New Features新增特性为 4 个核心 QL 类补充了 4 个新谓词覆盖模板推导指南、explicit 声明、destroying delete 释放函数识别Minor Analysis Improvements次要分析改进修正constexpr if的未求值语义、优化大函数体别名分析性能、新增UsingEnumDeclarationEntry类并调整using enum的条目合成行为。这些 API 定义在 cpp/ql/lib/semmle/code/cpp/ 目录下的 QLL 库模块中与其对应的 dbscheme 数据表cpp/ql/lib/semmlecode.cpp.dbscheme共同构成分析器与查询之间的接口层。二、DeductionGuide 类新增 getTemplateClass 谓词2.1 谓词语义DeductionGuide类表示 C 中的推导指南deduction guide即 C17 起用于指导类模板参数推导的声明。1.4.0 版本为其新增了getTemplateClass谓词用于获取该推导指南所服务的类模板TemplateClass getTemplateClass() { deduction_guide_for_class(underlyingElement(this), unresolveElement(result)) }该实现位于 cpp/ql/lib/semmle/code/cpp/Function.qll#L944-L953底层直接依赖 dbscheme 中的deduction_guide_for_class二元关系第一个参数是推导指南元素本身第二个参数是它为之服务的类模板。2.2 使用场景示例考虑如下 C17 代码template typename T struct Box { Box(T value); }; // 用户自定义推导指南 Box(int) - Boxint;对应查询可写成import cpp from DeductionGuide g, TemplateClass tc where tc g.getTemplateClass() select g, tc, 该推导指南服务于类模板 tc.getName()在 1.4.0 之前从DeductionGuide反向找到其目标类模板需要手工遍历声明上下文现在该关联关系被直接建模为一条谓词使围绕模板推导的分析如推导结果类型推断、隐式推导指南 vs 显式推导指南的区分更加直接。三、Function 类新增 explicit 检测谓词3.1 isExplicit判断是否声明为 explicitFunction类新增的isExplicit谓词用于判断函数是否被explicit关键字修饰predicate isExplicit() { this.hasSpecifier(explicit) }实现位于 cpp/ql/lib/semmle/code/cpp/Function.qll#L121-L124通过复用既有的说明符检查机制hasSpecifier实现。它适用于构造函数、转换运算符等所有可被声明为explicit的函数此前查询需要自行检查说明符集合现在可直接调用。3.2 getExplicitExpr获取条件 explicit 的常量表达式C20 引入了条件式explicit(expr)写法其布尔常量表达式在编译期决定构造函数或转换函数是否为 explicit。getExplicitExpr谓词用于取出这个表达式Expr getExplicitExpr() { explicit_specifier_exprs(underlyingElement(this), unresolveElement(result)) }实现位于 cpp/ql/lib/semmle/code/cpp/Function.qll#L126-L139库文档给出了典型示例templatetypename T struct C { explicit(sizeof(T) 1) C(const T); };对上述代码getExplicitExpr返回表达式sizeof(T) 1。借助该谓词分析器既可以判定“存在显式说明符”也可以进一步求值或分析决定显式性的常量表达式例如检查该表达式是否恒为真/假、是否依赖模板参数等。两个谓词可组合使用isExplicit()覆盖传统写法与explicit(expr)写法对于后者getExplicitExpr()提供表达式级别的可编程访问。四、destroying delete 释放函数识别4.1 背景destroying deleteC20 允许将类专属的operator delete声明为 destroying delete形式为operator delete(T*, std::destroying_delete_t)此时delete表达式会先调用析构函数再由该运算符负责销毁对象并释放内存。1.4.0 版本在NewOrNewArrayExpr与DeleteOrDeleteArrayExpr两个类上同时新增了isDestroyingDeleteDeallocation谓词。4.2 实现与底层数据表两个类上的实现一致例如 cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll#L969-L977NewOrNewArrayExpr与 cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll#L1144-L1152DeleteOrDeleteArrayExprpredicate isDestroyingDeleteDeallocation() { exists(int form | expr_deallocator(underlyingElement(this), _, form) and form.bitAnd(4) ! 0 // Bit two is the destroying delete bit ) }该实现基于 dbscheme 中的expr_deallocator关系定义于 cpp/ql/lib/semmlecode.cpp.dbscheme#L1609-L1613。该关系携带一个form整数列以位标志编码释放调用携带的参数信息位掩码含义bit 01释放函数带 size 参数sized deallocationbit 12释放函数带 alignment 参数aligned deallocationbit 24释放函数是 destroying delete同一文件中的hasSizedDeallocation()掩码1与hasAlignedDeallocation()掩码2早在之前版本就已存在1.4.0 新增的 bit 2 使三个特性得以统一在同一个位标志机制下建模。4.3 使用示例import cpp from DeleteExpr d, Function f where f d.getDeallocator() and d.isDestroyingDeleteDeallocation() select d, f, 该 delete 表达式使用的是 destroying delete 释放函数该谓词对于资源生命周期相关查询例如 double-delete、自定义删除器与析构顺序分析很有价值能够精确区分普通operator delete与 C20 destroying delete 两种释放路径。五、constexpr if 控制表达式识别为未求值1.4.0 修正了一个语义细节constexpr if即if constexpr的控制表达式现在总是被识别为未求值表达式unevaluated expression。Expr类中的isUnevaluated谓词定义于 cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll#L289-L304它说明“表达式因其所在上下文而不会被求值例如sizeof内部的表达式”其实现覆盖了SizeofOperator、非多态类型的typeid操作数等经典未求值上下文。本次变更将if constexpr的判定条件纳入同一语义范畴template typename T void f(T x) { if constexpr (sizeof(T) 4) { // 分支 A } else { // 分支 B } }其中sizeof(T) 4不会被运行时求值。此修正对依赖isUnevaluated的查询影响直接例如数据流分析不再认为该表达式中的操作数产生实际读取/写入避免在if constexpr分支中产生误报或漏报依赖表达式求值属性的别名分析与污点分析也会获得更一致的语义边界。六、大函数体别名分析性能改进6.1 变更内容1.4.0 改进了对大函数体的别名分析alias analysis性能。变更记录同时提示了一个潜在影响在极少数情况下依赖大函数体别名分析结果的告警alerts可能因结果集变化而受影响。6.2 影响范围与注意事项该改进位于分析引擎的别名分析实现层查询作者无需改动代码即可受益但需要注意别名分析是 C 数据流与指针分析的基础组件其性能直接影响大型函数数千行、大量局部变量与指针操作的查询耗时“极少数情况下告警可能受影响”意味着本次优化可能伴随求解顺序或保守近似策略的微调导致个别边界用例的结果发生变化。若团队基于旧版本建立了告警基线升级后建议对高度依赖别名分析的查询如悬垂指针、use-after-free、double-free 相关做一次回归验证。七、using enum 声明建模新增 UsingEnumDeclarationEntry 类7.1 新类定义C20 引入了using enum声明如using enum Foo;用于将枚举成员引入当前作用域。1.4.0 为此新增了UsingEnumDeclarationEntry类定义于 cpp/ql/lib/semmle/code/cpp/Namespace.qll#L223-L240class UsingEnumDeclarationEntry extends UsingEntry { UsingEnumDeclarationEntry() { usings(underlyingElement(this), _, _, 3) } Enum getEnum() { usings(underlyingElement(this), unresolveElement(result), _, _) } override string toString() { result using enum this.getEnum().getQualifiedName() } }usings关系以 kind 字段区分不同种类的 using 条目kind2对应UsingDirectiveEntryusing namespace std;见 Namespace.qll#L211-L221kind3则对应本版本新增的UsingEnumDeclarationEntry。新类提供getEnum()获取被引用的枚举类型toString()输出using enum Foo形式的限定名描述便于在结果中直接呈现。7.2 行为调整不再为单个枚举器合成 UsingDeclarationEntry与新增类配套1.4.0 还调整了条目的合成synthesized行为不再为using enum所引用枚举的每一个枚举器单独合成UsingDeclarationEntry。此前using enum Foo;会被展开为一组针对Foo::a、Foo::b等单个枚举器的 using 条目导致名称查找相关查询需要处理大量合成条目。本次变更将using enum作为整体建模为单一入口使基于UsingDeclarationEntry的名称解析/作用域查询结果更加简洁查询仍可通过UsingEnumDeclarationEntry.getEnum()拿到完整枚举再按需枚举其成员例如通过Enum.getEnumerator()。对于依赖旧行为的查询升级 1.4.0 后需要注意若查询遍历UsingDeclarationEntry并期望覆盖到using enum引用的枚举器需要显式追加对UsingEnumDeclarationEntry的处理分支。八、升级与查询迁移建议在查询模块头部import cpp后即可直接使用上述新谓词无需额外引入专用库文件isDestroyingDeleteDeallocation同时存在于 new 与 delete 两类表达式上编写资源生命周期查询时注意二者语义差异前者关注分配初始化异常时的释放路径后者关注普通delete路径若历史查询依赖if constexpr控制表达式的“已求值”行为或依赖using enum展开出的枚举器级UsingDeclarationEntry请按第六、七节说明调整逻辑并回归测试版本变更的完整历史可参考 cpp/ql/lib/CHANGELOG.md其中同步记录了 1.4.0 的上述全部条目便于在多版本升级时对照检索。赞分享静态分析SAST应用安全漏洞扫描代码质量【免费下载链接】codeqlCodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security项目地址https://gitcode.com/gh_mirrors/co/codeql点击查看免费下载相关推荐lowcode-engine 数据源面板详解从可视化配置到数据源引擎的完整生产消费链路lowcode engine 数据源面板详解从可视化配置到数据源引擎的完整生产消费链路 本篇以 lowcode engine 官方文档《数据源面板详解》为主体静态分析SAST应用安全漏洞扫描代码质量CodeQL C 库 0.3.1 变更深度解析AnalysedExpr 空值检查分析增强CodeQL C 库 0.3.1 变更深度解析AnalysedExpr 空值检查分析增强 本篇技术指南围绕 CodeQL C 查询库 cpp/ql静态分析SAST应用安全漏洞扫描代码质量CodeQL C 库 0.12.10 变更深度解析污点继承内容建模与守卫条件谓词增强CodeQL C 库 0.12.10 变更深度解析污点继承内容建模与守卫条件谓词增强 CodeQL 的 C 查询库 cpp/ql/lib 在 0.静态分析SAST应用安全漏洞扫描代码质量上一篇终极指南3分钟用AI读懂千万行代码附实战案例下一篇Obsidian终极性能优化实战从界面美化到效率革命的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表