CodeQL C++ 分析库 0.11.0 版本要点解析:Container/Folder 位置模型重构、AdditionalCallTarget 调用图扩展与 C23/C++23 浮点类型支持

发布时间:2026/9/26 2:35:30
CodeQL C++ 分析库 0.11.0 版本要点解析:Container/Folder 位置模型重构、AdditionalCallTarget 调用图扩展与 C23/C++23 浮点类型支持 静态分析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点击查看免费下载导读本文基于 cpp/ql/lib/change-notes/released/0.11.0.md 发布说明深入解读 CodeQL C 分析库 0.11.0 版本的三类变更破坏性变更Container/Folder的位置模型从Locatable迁移到ElementBase、新特性AdditionalCallTarget数据流扩展点、以及两项分析改进隐式this字段访问识别、C23/C23 新浮点类型支持。读完本文你将掌握该版本升级时查询代码的迁移要点并理解每个变更在cpp/ql/lib源码中的具体实现位置与工作原理从而能够安全升级查询并利用新能力编写更精确的数据流分析。版本概览这次发布改了什么0.11.0 是 CodeQL C 查询库即cpp/ql/lib目录下的 QL 库代码的一个中间版本发布其变更记录同步收录在 cpp/ql/lib/CHANGELOG.md 中。整个版本围绕三个层面展开破坏性变更Breaking ChangesContainer与Folder两个类的继承关系与 API 发生变化直接影响依赖getLocation的既有查询新特性New Features引入AdditionalCallTarget类为 IR 数据流分析提供补充调用目标的扩展接口次要分析改进Minor Analysis Improvements扩大ImplicitThisFieldAccess的识别范围并新增对 C23 与 C23 浮点类型的建模。下面分别从源码层面逐一拆解。破坏性变更Container 与 Folder 从 Locatable 迁移到 ElementBase变更内容发布说明原文如下TheContainerandFolderclasses now derive fromElementBaseinstead ofLocatable, and no longer expose thegetLocationpredicate. UsegetURLinstead.也就是说Container文件或文件夹的抽象与Folder构建过程中在磁盘上观察到的文件夹这两个类基类从Locatable改为ElementBase不再暴露getLocation谓词需要定位信息时改用getURL。源码层面的实现这一变更直接体现在 cpp/ql/lib/semmle/code/cpp/File.qll 的类定义中// File.qll class Container extends ElementBase, Impl::Container { override string toString() { result Impl::Container.super.toString() } } class Folder extends Container, Impl::Folder { override string getAPrimaryQlClass() { result Folder } } class File extends Container, Locatable, Impl::File { ... }从源码结构可以看到关键差异Container与Folder现在直接派生自ElementBase不再经过Locatable因此失去了Locatable提供的getLocation能力与此对照File类仍然同时继承Container与Locatable并重写了getLocationFile.qll#L65-L71所以仅针对File的查询不受此次变更影响ElementBase在 cpp/ql/lib/semmle/code/cpp/Element.qll 中被定义为element的直接根类。该文件的注释明确指出扩展ElementBase而非Element是为getURL、getLocation、hasLocationInfo创建新的根定义rootdef。因此Container/Folder现在通过ElementBase的根定义获取getURL能力而不再通过Locatable的位置体系。查询迁移与改写示例如果你的自定义查询或企业级定制查询中存在类似下面的写法// 旧写法0.11.0 之前 from Folder f where f.getLocation().getFile() ... select f则需要改写为基于getURL的定位方式// 新写法0.11.0 起 from Folder f where f.getURL() ... select f需要注意两点getURL返回的是字符串形式的文件系统定位在 CodeQL 中即file://风格的路径表示而getLocation返回的是Location对象二者类型不同涉及位置比较、行号计算的逻辑需要一并调整由于Container仍然提供getAbsolutePath、getBaseName、getParentContainer等路径分解能力见File.qll中Impl::Container的实现如ContainerBase.getParentContainer与toString纯粹的路径访问不受影响只有依赖Location对象的代码需要迁移。新特性AdditionalCallTarget —— 为数据流补充调用目标动机调用图不完整时的数据流缺口CodeQL 的 IR 数据流分析依赖调用图来确定Call的可能目标进而沿着调用边界传播污点或数据。但在某些场景下例如通过函数指针、回调注册、或框架动态分发调用默认的调用图解析无法找到目标导致数据流在调用点被切断。AdditionalCallTarget就是为了让查询作者手工声明额外调用目标而设计的扩展点。源码实现该类定义在 cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll/** * A unit class for adding additional call steps. * * Extend this class to add additional call steps to the data flow graph. */ class AdditionalCallTarget extends Unit { /** * Gets a viable target for call. */ abstract Declaration viableTarget(Call call); }它是一个abstract类核心是一个抽象谓词viableTarget(Call call)对于给定的调用表达式返回一个可行的Declaration作为目标。与getARuntimeTargetDataFlowUtil.qll#L1002-L1008基于DataFlowDispatch::viableCallable的运行时目标解析不同AdditionalCallTarget完全由查询作者在 QL 层声明不依赖提取器或调用图数据。使用示例DataFlowUtil.qll的注释中给出了一个完整的实战示例假设调用f(x)时实际目标应当是g(x)则先声明子类import semmle.code.cpp.ir.dataflow.DataFlow class MyAdditionalCallTarget extends DataFlow::AdditionalCallTarget { override Function viableTarget(Call call) { call.getTarget().hasName(f) and result.hasName(g) } }随后在下面的 C 代码中从source()到sink(x)的数据流就会被成功追踪void sink(int); int source(); void f(int); void g(int x) { sink(x); } void test() { int x source(); f(x); }这个例子清晰地说明了该特性的价值f与g之间本没有直接调用关系但通过AdditionalCallTarget声明数据流分析便能把f(x)的实参流向g(x)的形参从而连通source→sink路径。使用注意事项源码注释特别强调了一个重要约束To prevent reevaluation of cached dataflow-related predicates any subclass ofAdditionalCallTargetmust be imported in all dataflow queries.也就是说任何AdditionalCallTarget的子类都必须被所有数据流查询导入否则数据流相关的缓存谓词可能被重复求值导致分析结果不一致或性能退化。这意味着该扩展点适合放在共享的 QLL 库模块中而不是散落在单个查询里。分析改进一更多字段访问被识别为 ImplicitThisFieldAccess变更内容More field accesses are identified asImplicitThisFieldAccess.ImplicitThisFieldAccess用于表示隐式this-字段访问——即类成员函数中直接写字段名、省略this-限定的访问形式。这类访问在语法上看起来只是裸字段名但对别名分析、SSA 与数据流来说明确标注其隐式通过this指针的性质至关重要。源码中的判定逻辑该类定义在 cpp/ql/lib/semmle/code/cpp/exprs/Access.qllclass ImplicitThisFieldAccess extends FieldAccess { override string getAPrimaryQlClass() { result ImplicitThisFieldAccess } ImplicitThisFieldAccess() { this.getQualifier().(ThisExpr).isCompilerGenerated() or not exists(this.getQualifier()) } }判定条件有二限定符是编译器生成的ThisExpr即this-x中this由编译器隐式补出或者不存在限定符即裸的x字段访问。此次变更扩大了识别范围使更多满足上述条件的字段访问落入该类别。从类层次上看它同时被PointerToFieldLiteral指向非静态数据成员的指针字面量如C::x复用——后者正是没有限定符的字段访问的特例Access.qll#L327-L336这说明ImplicitThisFieldAccess在表达式分类体系中承担着承上启下的作用。依赖该分类的查询如别名与成员访问一致性分析将在升级后自动获得更完整的覆盖。分析改进二新增 C23 与 C23 浮点类型支持变更内容Added support for new floating-point types in C23 and C23.C23 与 C23 分别引入了新一代浮点类型如_Float16、_Float128及对应的 C 标准类型std::float16_t等其底层表示、运算语义与既有的float/double/long double并不相同。若 QL 库无法识别这些类型涉及它们的算术运算、类型转换与溢出分析都会失真。源码中的类型映射支持逻辑集中在 cpp/ql/lib/semmle/code/cpp/Type.qll 的FloatingPointType及其子类体系中。FloatingPointType通过floatingPointTypeMapping(kind, base, domain, realKind, extended)将提取器产生的内置类型编号映射为 QL 类型Type.qll#L868-L879例如// _Float128 kind 49 and base 2 and domain TRealDomain() and realKind 49 and extended false // _Float16 kind 52 and base 2 and domain TRealDomain() and realKind 52 and extended false // _Complex _Float128 kind 61 and base 2 and domain TComplexDomain() and realKind 49 and extended false围绕该映射库中提供了完整的类型层次便于查询按需细分RealNumberType/ComplexNumberType/ImaginaryNumberType按实数、复数、虚数域划分Type.qll#L904-L920BinaryFloatingPointType/DecimalFloatingPointType按基数 2 与基数 10 划分Type.qll#L925-L934。也就是说0.11.0 之后涉及新浮点类型的表达式如对_Float16变量的算术运算会被正确归类为FloatingPointType的子类型从而被算术与类型相关的分析如溢出检测、类型宽度比较查询纳入考虑范围。查询作者可以利用上述细分类型编写针对新浮点语义的专用规则。升级与兼容性指引综合以上变更从 0.11.0 之前的版本升级到该版本时建议按以下顺序处理全局检索getLocation在Container/Folder上的使用将针对文件、文件夹对象的getLocation()调用改写为getURL()并同步调整依赖Location对象的比较与行号计算逻辑File类不受影响可保持原样。如依赖跨调用的数据流评估AdditionalCallTarget若存在调用图解析不到目标的数据流缺口可新建子类声明补充目标并确保在所有数据流查询中导入该子类所在模块。重新校验算术与类型相关查询的结果ImplicitThisFieldAccess覆盖扩大与 C23/C23 浮点类型建模都可能改变既有查询的结果集建议结合cpp/ql/lib下的测试用例位于cpp/ql/test目录重新运行回归测试确认无意外的结果变化。小结CodeQL C 分析库 0.11.0 是一次有取舍、有新增、有深化的版本发布破坏性变更把Container/Folder的位置模型切换到ElementBase根类File.qll换取更统一的getURL定位体系新特性AdditionalCallTargetDataFlowUtil.qll把补充调用目标的能力开放给查询作者填补了动态分派场景下数据流的缺口两项分析改进分别提升了隐式this字段访问的识别覆盖率Access.qll与新一代浮点类型的建模精度Type.qll。对于维护自定义 C 查询的团队而言升级到该版本的关键动作是完成getLocation→getURL的迁移并利用AdditionalCallTarget与新浮点类型建模提升分析的准确度。赞分享静态分析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 1.26 C/C 分析改进解析查询精度调整与库级污点流模型扩展CodeQL 1.26 C/C 分析改进解析查询精度调整与库级污点流模型扩展 本文基于 CodeQL 仓库中 1.26 版本的 C/C 分析变更说明静态分析SAST应用安全漏洞扫描代码质量CodeQL 1.24 C/C 分析改进全解析新查询、污点追踪库重构与库建模升级CodeQL 1.24 C/C 分析改进全解析新查询、污点追踪库重构与库建模升级 本篇指南完整梳理 CodeQL 1.24 版本针对 C/C 分析的所静态分析SAST应用安全漏洞扫描代码质量CodeQL C 分析库中的 cstdint 标准类型建模FixedWidthIntegralType 与 FixedWidthEnumType 详解CodeQL C 分析库中的 cstdint 标准类型建模FixedWidthIntegralType 与 FixedWidthEnumType 详解 本静态分析SAST应用安全漏洞扫描代码质量上一篇protobuf-net流式序列化处理大型数据集的最佳方法下一篇LeadQualifier特征工程深度解析CountVectorizer与TF-IDF为什么是线索分类的关键创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考