news 2026/11/5 12:32:55

CodeQL C/C++ 查询库 7.0.0 变更解析:API 演进、C++23 多维下标支持与数据流屏障修复

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CodeQL C/C++ 查询库 7.0.0 变更解析:API 演进、C++23 多维下标支持与数据流屏障修复
  • 静态分析
  • SAST
  • 应用安全
  • 漏洞扫描
  • 代码质量

【免费下载链接】codeql

CodeQL: 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
点击查看免费下载

本篇技术指南以 C++ 查询库 7.0.0 发布说明 为骨架,逐条拆解该版本引入的破坏性变更、API 弃用与新增能力、常量分析行为调整,以及数据流屏障谓词的缺陷修复,并结合 Call.qll、Access.qll、Ssa.qll 等源码给出实现级佐证。读完本文,你将掌握 7.0.0 中各 API 的准确迁移路径(如何替换被弃用的谓词、如何适配屏障节点语义变化),并能据此评估升级对既有 C/C++ 查询的影响。

版本发布说明在仓库中的位置与阅读方式

该文档位于cpp/ql/lib/change-notes/released/目录,与 0.0.x、6.x、8.x、9.x 等历代版本的说明并列存放,完整记录了 C/C++ 查询库 qlpack 自发布以来的每一次 API 变化。7.0.0 的变更条目按 CodeQL 变更说明的惯例分为五类:

  • Breaking Changes:破坏性变更,升级后可能影响既有查询的编译或结果;
  • Deprecated APIs:已弃用但仍可使用的 API,应尽快迁移;
  • New Features:新增的类、谓词与内建操作支持;
  • Minor Analysis Improvements:分析精度的细微调整;
  • Bug Fixes:缺陷修复,可能改变查询结果。

这些条目同样被汇总进了 cpp/ql/lib/CHANGELOG.md,便于按版本号检索。下面逐类展开。

Breaking Changes:_Decimal32/64/128不再作为内建类型暴露

7.0.0 最直接的破坏性变更是:_Decimal32、_Decimal64、_Decimal128这三个 GCC 特有的十进制浮点类型,不再被 CodeQL 暴露为内建类型(builtin types)。

文档给出的理由有两层:

  1. 对这些类型的支持本身不完整("Support for these gcc-specific types was incomplete"),即此前的建模存在缺口;
  2. 这类类型在真实 C/C++ 代码库中很少使用("generally not used in C/C++ codebases"),投入产出比低。

对查询作者的实际影响:任何在查询中直接引用这三个类型名(例如在类型模式、instanceof判断或getType().getName()比较中匹配_Decimal32等字符串)的既有查询,升级后可能不再命中或无法解析对应类型实体。如果确实需要处理这类代码,建议改用更通用的数值类型建模路径,或基于类型特征的间接匹配方式,而不是依赖内建类型名的直接引用。

Deprecated APIs:OverloadedArrayExpr::getArrayOffset/0弃用与迁移

背景:OverloadedArrayExpr是什么

在 Call.qll 中,OverloadedArrayExpr被定义为"用户自定义二元operator[]作用于其参数的一次实例",即重载下标运算符的调用表达式。典型场景:

struct T2 { T1 operator[](const T3 &); }; T1 a; T2 b; T3 c; a = b[c]; // 这里 b[c] 就是一个 OverloadedArrayExpr

源码中该类通过this.getTarget().hasName("operator[]")识别目标函数,并提供两个基础访问器:

  • getArrayBase():被下标的对象表达式(优先取限定符getQualifier(),否则取第 0 个子节点);
  • 下标索引相关的getArrayOffset系列谓词。

弃用细节与推荐替代

7.0.0 将无参版本getArrayOffset/0标记为deprecated(见 Call.qll#L388-L393),其旧实现等价于getArrayOffset(0),即"取第一个(第 0 个)下标"。弃用后的推荐写法:

  • OverloadedArrayExpr::getArrayOffset/1:按索引取第 n 个下标表达式;
  • OverloadedArrayExpr::getAnArrayOffset:取任意一个下标表达式(数量不限)。

从实现看,getArrayOffset(int n)在存在限定符时返回this.getChild(n),否则返回this.getChild(n + 1)(因为此时第 0 个子节点是被下标对象本身),而getAnArrayOffset只是对getArrayOffset(_)的存在量化封装。也就是说:只要你的查询需要访问"第一个下标"的语义,把getArrayOffset()替换成getArrayOffset(0)即可获得完全一致的行为;需要遍历全部下标时则改用getAnArrayOffset。被弃用的谓词在本版本中仍可用,但会在后续版本移除,建议尽早迁移。

New Features:三项新增能力

1.__is_bitwise_cloneable、__is_invocable、__is_nothrow_invocable内建操作子类

7.0.0 为BuiltInOperations增加了三个新的子类,对应三种编译器内建操作(见 BuiltInOperations.qll):

新增类对应内建语义
位可克隆性检查__is_bitwise_cloneable判断类型是否可按位复制(常用于is_bitwise_cloneable这类 traits 的实现)
可调用性检查__is_invocable判断函数类型/参数包是否可被调用(std::is_invocable的底层实现)
无异常可调用性检查__is_nothrow_invocable判断调用是否保证不抛异常(std::is_nothrow_invocable的底层实现)

在此之前,这类表达式可能只能被当作泛化的内建调用处理,无法用具体子类精确匹配。新增子类后,查询作者可以直接按instanceof分支或在BuiltInOperations的getAPrimaryQlClass分派中区分这三种操作,便于围绕 C++ 类型特征(traits)展开更精细的分析。

2.ParamAccessForType::isThisAccess:识别隐式对象参数访问

ParamAccessForType表示"为decltype目的而对函数签名参数进行的访问"。典型场景:

template <typename L, typename R> auto add(L lhs, R rhs) -> decltype(lhs + rhs) { return lhs + rhs; }

这里返回类型decltype(lhs + rhs)内部是一个加法表达式,其两个子节点都是ParamAccessForType(见 Access.qll#L382-L402)。

新谓词isThisAccess在该访问指向函数的隐式对象参数(即成员函数的this)时成立,实现上依赖param_ref_to_this(underlyingElement(this))这一底层关系。对分析decltype上下文中的this引用、以及在类型层面建模成员函数签名时,这个谓词提供了直接、可判定的判断入口,无需再自行推导"该参数引用是否为 this"。

3.getArrayOffset/1与getAnArrayOffset:支撑 C++23 多维下标运算符

C++23 允许用户为类类型重载多维下标运算符,例如a[i, j, k]。这意味着一个OverloadedArrayExpr可能携带多个下标表达式,而旧版getArrayOffset/0只能取到第一个下标,信息不完整。

7.0.0 通过新增两个谓词补齐这一能力:

  • getArrayOffset(int n):按位序取第 n 个下标(n >= 0),支持访问任意维度;
  • getAnArrayOffset:不限定维度地枚举所有下标表达式。

两者已在 Call.qll#L395-L406 落地。配套地,原getArrayOffset/0被弃用(见上文),避免查询作者继续使用"只能取第一个下标"的旧语义而漏掉多维场景。对于编写数组越界、下标污染(taint)等与下标相关的 C/C++ 安全查询,这是一个需要同步跟进的重要 API 变化。

Minor Analysis Improvements:常量改为展开的表达式树表示

7.0.0 调整了常量的表示方式:部分常量不再以折叠后的单值形式存在,而改用其展开的表达式树(unfolded expression trees)来表示。由此带来一个直接后果:Expr的isConstant谓词对这些常量不再成立(不再返回结果)。

结合 Expr.qll#L188-L195 的实现来看,isConstant目前由三类来源支撑:

  • valuebind(_, underlyingElement(this)):与提取器写入的值绑定表关联的常量;
  • addressConstantExpression(this):地址常量表达式(如函数地址、constexpr 变量地址、lvalue 地址及其加减常量);
  • constantTemplateLiteral(this):未实例化模板中的常量模板字面量。

"展开的表达式树"表示意味着某些常量在 AST 中保留了完整的运算结构(例如1 + 2不再直接折叠成字面量3),因此无法再从值绑定中直接命中,isConstant也就不再成立。

影响评估:依赖isConstant判断"表达式是否为编译期常量"的查询(如 RangeAnalysisUtils.qll、Scanf.qll 中对常量操作数的依赖)可能观察到行为变化。如果你的查询需要同时覆盖折叠常量与展开表达式,应结合 AST 结构(如Constant字面量、FoldExpr等)与isConstant共同判断,而不是单独依赖单一谓词。

Bug Fixes:BarrierGuard::getABarrierNode的间接寻址缺陷修复

缺陷本质

7.0.0 修复了DataFlow::BarrierGuard<...>::getABarrierNode中的一个 bug:该谓词此前会返回带有错误间接层级(indirections)的DataFlow::Node。也就是说,屏障节点所对应的数据流值层级与实际守卫对象不符,可能导致isBarrier/isSanitizer中基于getABarrierNode实现的屏障未能正确拦截污点传播。

从 Ssa.qll#L2079-L2090 的实现脉络看,BarrierGuard模块通过BarrierGuardWithState把"守卫检查谓词"(guardChecks(g, e, val))与 SSA 定义/读取关联起来,getABarrierNode最终聚合出"被该守卫安全检查的节点"。间接层级错误意味着聚合出的节点在其指针/引用层级上与守卫表达式不一致。

对你的查询的影响

修复后,如果你用getABarrierNode实现 dataflow/taint-tracking 查询的屏障,可能会看到更多的查询结果(更多告警)——因为此前错误层级掩盖了部分本应被判定为"受污染数据仍可达"的路径。文档给出的应对方案:

  • 若新增结果属于误报,可使用DataFlow::BarrierGuard<...>::getAnIndirectBarrierNode来移除这些额外结果;
  • 换言之,getABarrierNode现在只应匹配"恰好与该守卫值层级一致"的节点,而getAnIndirectBarrierNode用于覆盖经间接访问(如指针解引用、成员访问)后仍受守卫保护的情况。

迁移建议:升级到 7.0.0 后,请重新跑一遍依赖屏障机制的 dataflow/taint 查询,对比结果集变化;在isBarrier/isSanitizer中按需将getABarrierNode替换为getAnIndirectBarrierNode,并根据告警的增减判断取舍。该谓词定义于共享模块 shared/ssa/codeql/ssa/Ssa.qll,被各语言查询库的数据流库复用,因此这一修复的影响面不限于 C/C++ 查询。

升级核对清单

综合以上五类变更,从 6.x 升级到 7.0.0 时建议逐项核对:

  1. 搜索弃用调用:检查查询中所有OverloadedArrayExpr的.getArrayOffset()无参调用,替换为getArrayOffset(0)或getAnArrayOffset;
  2. 复查类型引用:确认没有查询依赖_Decimal32/64/128内建类型名;
  3. 重跑屏障相关查询:对使用BarrierGuard的 dataflow/taint 查询做结果对比,按需改用getAnIndirectBarrierNode;
  4. 复核常量判断:对依赖isConstant的查询补充 AST 结构判断,避免常量展开表示带来的漏报;
  5. 新能力接入:如需处理 C++23 多维下标或decltype中的this访问,直接使用新增的getArrayOffset/1、getAnArrayOffset与isThisAccess。

各变更条目的官方记录以 7.0.0 发布说明 为准,并可在 cpp/ql/lib/CHANGELOG.md 中按版本检索到完整演进历史。升级前建议在目标查询集上运行一次全量回归测试,以量化结果集变化。

  • 静态分析
  • SAST
  • 应用安全
  • 漏洞扫描
  • 代码质量

【免费下载链接】codeql

CodeQL: 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
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/25 3:03:40

操作简便吗?8款AI写作辅助平台势力榜,毕业论文轻松搞定!

写论文时是否总感觉思路混乱&#xff0c;无从下手&#xff1f;查重反复修改&#xff0c;却总不达标&#xff1f;格式调整繁琐&#xff0c;耗时又费力&#xff1f; 别担心&#xff01;AI论文写作工具正成为高校学生的高效帮手。本文将基于学术规范性、文献引用能力、查重优化效…

作者头像 李华
网站建设 2026/11/4 22:28:08

中国移动云盘解析下载 无删减资源获取与使用说明

中国移动云盘解析下载 无删减资源获取与使用说明https://pan.baidu.com/s/1MF4J0vRWJavkeAwUXwICkQ?pwd5hch 点击获取资源&#xff1a; 【名称与分类】这份中国移动云盘解析下载是一份优质的资源资料&#xff0c;内容丰富、整理规范。 【功能概述】资料分类清晰、查找方便&…

作者头像 李华
网站建设 2026/10/22 18:04:51

企业资质认证怎么做?从初创到成熟的四阶段规划指南

企业在经营过程中面临的合规风险&#xff0c;往往不是来自业务本身&#xff0c;而是来自资质缺失。一项统计显示&#xff0c;超过 60% 的中小企业在成立前三年曾因资质不全遭遇过行政处罚或业务中断。资质认证不是事后补救的应急动作&#xff0c;而是伴随企业生命周期的系统性工…

作者头像 李华
网站建设 2026/10/31 19:22:45

红帽 AI 推理服务(vLLM)实战:用 GuideLLM 评估 LLM 模型性能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/5 11:10:42

零依赖纯文本知识库:用文件夹+Git搭建永不过期的个人笔记系统

caveman 是我最近一直挂在嘴边的一个小项目代号&#xff0c;外号叫“穴居人方案”。圈子里偶尔看到叫 caveman 的工具或开源项目&#xff0c;思路大多差不多&#xff1a;把知识管理这件事打回原形&#xff0c;不用花哨的 App&#xff0c;不用云端数据库&#xff0c;就用文件夹、…

作者头像 李华