CodeQL C 库对 C 9 unary `not` 模式的完整支持:UnaryPatternExpr 与 NotPatternExpr 解析

发布时间:2026/10/7 9:40:31

CodeQL C 库对 C 9 unary `not` 模式的完整支持:UnaryPatternExpr 与 NotPatternExpr 解析 静态分析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点击查看免费下载本文基于 csharp/old-change-notes/2021-01-14-Unary-pattern.md 这一变更说明展开。它记录了 CodeQL 的 C# 分析库为支持 C# 9 一元not模式unary not pattern而新增的UnaryPatternExpr与NotPatternExpr两个 QL 类。读者读完本文后将能够理解这两个 QL 类在类层次中的位置与 API掌握not模式从 Roslyn 语法树经提取器落入 TRAP 的完整链路并了解守卫分析guards如何利用NotPatternExpr推导null匹配与相等性测试的极性从而在数据流与污点分析中获得更精确的路径条件。变更说明原文与适用范围原文档 2021-01-14-Unary-pattern.md 全文如下lgtm,codescanning * The UnaryPatternExpr and NotPatternExpr classes have been added to support C# 9 unary not pattern.其中lgtm,codescanning是该变更说明的适用标签labels表示这项库变更同时纳入 LGTM 与 GitHub code scanning 两个产品的查询集发布核心内容是为支持 C# 9 的一元not模式在 QL 库中新增了UnaryPatternExpr与NotPatternExpr两个类。C# 9 的模式匹配语法pattern matching引入了几种组合模式combinator patterns其中一元not模式形如not pattern用于否定一个子模式例如x is not null、c is not a、i is not 1。此后CodeQL 的 C# 分析库可以在is表达式、switch表达式与switch语句中识别并分析这类模式从而正确建模其布尔语义。QL 类层次UnaryPatternExpr 与 NotPatternExpr 的定义两个新类都定义在 csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll 中位于模式表达式pattern expression家族内/** A unary pattern. For example, not 1. */ class UnaryPatternExpr extends PatternExpr, unary_pattern_expr { /** Gets the underlying pattern. */ PatternExpr getPattern() { result this.getChild(0) } } /** A not pattern. For example, not 1. */ class NotPatternExpr extends UnaryPatternExpr, not_pattern_expr { override string toString() { result not ... } override string getAPrimaryQlClass() { result NotPatternExpr } }要点UnaryPatternExpr继承自PatternExpr并关联数据库实体unary_pattern_expr。它只有一个核心 APIgetPattern()返回not关键字后的一元子模式即this.getChild(0)例如not 1中的常量模式1NotPatternExpr继承UnaryPatternExpr关联not_pattern_expr重写了toString()输出为not ...与getAPrimaryQlClass()。它是一元模式在当前库中的具体化——当前 C# 语法中的一元模式即not模式因此NotPatternExpr是UnaryPatternExpr唯一的直接子类从 Expr.qll 的getAChildExpr()实现可以看到unary_pattern_expr被纳入模式子表达式的遍历逻辑exists(Expr mid | hasChildPattern(pm, mid) and mid instanceof unary_pattern_expr | child mid.getChildExpr(0))。这意味着在 AST 遍历中not模式内部嵌套的子模式如常量模式、递归模式会被正确枚举供各类查询访问。在Expr.qll的同一段代码中还可以看到与之相邻的组合模式类BinaryPatternExpr/OrPatternExpr/AndPatternExpr如1 or 2、 1 and 2、ListPatternExpr、SlicePatternExpr等它们共同构成 C# 9 模式语法的 QL 镜像。提取器从 RoslynUnaryPatternSyntax到 TRAP 实体QL 类只是数据库上的视图真正将源码中的not模式写入 TRAP 数据库的是 C# 提取器。提取器使用 RoslynMicrosoft.CodeAnalysis解析 C# 9 源码not模式对应语法节点UnaryPatternSyntax。入口位于 csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cscase UnaryPatternSyntax unaryPattern: return new UnaryPattern(cx, unaryPattern, parent, child);实体类 csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs 的实现internal class UnaryPattern : Expression { public UnaryPattern(Context cx, UnaryPatternSyntax syntax, IExpressionParentEntity parent, int child) : base(new ExpressionInfo(cx, cx.GetConvertedType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, isCompilerGenerated: false, null)) { Pattern.Create(cx, syntax.Pattern, this, 0); } }关键细节提取器把UnaryPatternSyntax归类为ExprKind.NOT_PATTERN与 QL 侧NotPatternExpr关联的not_pattern_expr实体一一对应Pattern.Create(cx, syntax.Pattern, this, 0)递归提取not关键字之后的子模式syntax.Pattern以child 0挂到当前实体之下——这正是 QL 侧getPattern()返回this.getChild(0)的来源类被声明为internal且命名空间为Semmle.Extraction.CSharp.Entities.Expressions表明它是提取器内部实现细节外部仅通过 QL 类NotPatternExpr暴露。从源码结构看该提取分支位于Pattern.Create工厂方法的 switch 中与常量模式、递归模式、位置模式等并存说明not模式被当作一等公民接入既有的模式提取体系。分析库中的应用守卫分析对 not 模式的推理新增的 QL 类并非仅供 AST 查询展示而是被集成进核心分析库。最有代表性的是 csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll 中的守卫guard推理——数据流分析依靠守卫来精确描述分支条件下的值域。相等性测试的极性反转在equalityTest谓词中Guards.qllis表达式与常量模式的组合会被建模为相等性测试而not模式会翻转极性exists(IsExpr ie, PatternExpr pat | ie eqtest and ie.getExpr() left and ie.getPattern() pat | right pat.(ConstantPatternExpr) and polarity true or right pat.(NotPatternExpr).getPattern().(ConstantPatternExpr) and polarity false )也就是说x is 1被识别为正极性相等测试而x is not 1通过pat.(NotPatternExpr).getPattern().(ConstantPatternExpr)解包出常量子模式并标注为反极性不等测试。这样一来if (x is not 1)分支内的分析就能正确推导出x ! 1的约束。null 匹配的布尔取反patternMatchesNull谓词Guards.qll递归计算某模式是否匹配null其中对NotPatternExpr做了显式处理private boolean patternMatchesNull(PatternExpr pat) { pat instanceof NullLiteral and result true or not pat instanceof NullLiteral and not pat instanceof NotPatternExpr and not pat instanceof OrPatternExpr and not pat instanceof AndPatternExpr and result false or result patternMatchesNull(pat.(NotPatternExpr).getPattern()).booleanNot() or exists(OrPatternExpr ope | pat ope | ...) or exists(AndPatternExpr ape | pat ape | ...) }这里result patternMatchesNull(pat.(NotPatternExpr).getPattern()).booleanNot()直接对子模式的 null 匹配结果取反x is not null因此被正确判定为匹配 null 为假、匹配非 null 为真与or/and组合模式的递归规则共同构成完整的模式 null 语义。这也是c is not null这类判空守卫能够参与空指针相关分析与净化器建模的基础。测试验证control flow 图中的 not 模式覆盖仓库在 csharp/ql/test/library-tests/controlflow/graph/Patterns.cs 中提供了覆盖各种not用法的测试源码例如public static bool M2(char c) c is not a; // not 常量模式 public static bool M3(object c) c is not null ? c is 1 : c is 2; // not null 字面量 public static bool M4(object c) c is not Patterns { P1: 1 } u; // not 递归属性模式 public static string M5(int i) i switch { not 1 not 1, _ other }; // switch 表达式 public static string M6() 2 switch { not 2 impossible, 2 possible }; public static string M8(int i) i is 1 or not 2 ? not 2 : 2; // not 与 or 组合 public static string M9(int i) i is 1 and not 2 ? 1 : not 1; // not 与 and 组合对应的期望输出 BasicBlock.expected 中出现了形如After not ... [match]与not 1的控制流标签证明控制流图CFG构建阶段能够正确处理not模式的匹配节点及其后继分支覆盖了模式匹配成立/不成立两条路径。这说明本次变更不仅是纯语法层面的 AST 支持还贯通了 CFG 与守卫推理保证基于not模式的布尔逻辑不会在后续分析如可达性、数据流中丢失。使用建议与注意事项版本前提not模式是 C# 9 语法需要目标源码以支持 C# 9 的编译器/Roslyn 版本编译CodeQL 的 C# 提取器通过UnaryPatternSyntax识别因此对源码本身的工程配置没有额外要求只要分析数据库是由新版本提取器生成即可查询到NotPatternExpr在查询中的用法如需在自定义查询中匹配取非判断可用pat instanceof NotPatternExpr并调用pat.getPattern()取得被否定的子模式例如在Guards.qll中那样结合ConstantPatternExpr还原出被比较的常量如需匹配任意一元模式可使用父类UnaryPatternExpr它保留了未来扩展到其他一元模式若 C# 后续版本引入的余地组合模式遍历由于 Expr.qll 已把unary_pattern_expr纳入getAChildExpr()递归基于Expr的通用遍历类查询可以无感知地穿透not模式访问其内部子模式无需针对NotPatternExpr写特殊处理分支语义正确性not模式匹配null的语义由 Guards.qll 的递归规则保证与 C# 规范一致not null匹配所有非 null 值在编写依赖守卫推导的自定义数据流配置时可以直接复用该基础设施。小结2021-01-14-Unary-pattern.md这一变更说明虽然简短却标志着一个完整的支持链提取器UnaryPattern.csExprKind.NOT_PATTERN→ QL 类Expr.qll 中的UnaryPatternExpr/NotPatternExpr→ 分析库Guards.qll 的相等测试与 null 匹配推理→ 测试Patterns.cs 与 BasicBlock.expected。对于编写或扩展 C# 查询的开发者而言理解这两个类及其在守卫分析中的角色是让自定义分析正确处理 C# 9 模式匹配语义的关键一步。赞分享静态分析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点击查看免费下载相关推荐mermaid-ascii子图subgraph完全指南嵌套分组布局与标题渲染mermaid ascii子图subgraph完全指南嵌套分组布局与标题渲染 mermaid ascii 是一个在终端中渲染 Mermaid 图表的命令行工具静态分析SAST应用安全漏洞扫描代码质量CodeQL C 库 2.1.0 新特性深度解析函数指针调用解析、隐式声明识别与 C20 requires 表达式支持CodeQL C 库 2.1.0 新特性深度解析函数指针调用解析、隐式声明识别与 C20 requires 表达式支持 本篇文章围绕 CodeQL 仓静态分析SAST应用安全漏洞扫描代码质量CodeQL C 库 0.0.12 版本解析TaintTracking API 重构、Flow State 支持与模板隐式复制语义修复CodeQL C 库 0.0.12 版本解析TaintTracking API 重构、Flow State 支持与模板隐式复制语义修复 本文基于 cpp/静态分析SAST应用安全漏洞扫描代码质量上一篇OR-Tools优化算法实战3个核心场景教你如何高效解决复杂运筹问题下一篇颠覆传统PDF管理极简页面编辑工具如何让300页文档处理效率提升80%创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/7 9:40:31

GPT-SoVITS hps未定义报错:3步快速修复指南

GPT-SoVITS hps未定义报错:3步快速修复指南 【免费下载链接】GPT-SoVITS 1 min voice data can also be used to train a good TTS model! (few shot voice cloning) 项目地址: https://gitcode.com/GitHub_Trending/gp/GPT-SoVITS 装好环境、打开网页、点下…

2026/10/7 10:30:42

零依赖PHP短链服务实战:原生代码+SQLite打造极简URL缩短器

最近 caveman 这个词在热搜上露脸的时候,我还愣了一下——这不就是我折腾过好几次的那套极简思维吗?项目本身不大,但背后的取舍过程,倒是很值得拆开来讲讲。这里说的 caveman,是我给自己的一个 URL 短链服务起的名字。…

2026/10/7 10:30:42

游戏引擎基础架构拆解:分层、核心模块与ECS

实话说,搞游戏开发的朋友,不管你是写玩法逻辑还是做引擎工具,迟早都会碰到一个绕不开的话题:游戏引擎架构。尤其是当你从“用引擎”切换到“看引擎”“改引擎”甚至“写引擎”的时候,最直观的感受就是——这玩意儿怎么…

2026/10/7 10:30:42

深入拆解RoCE网络:PFC、ECN与DCQCN机制与调优

最近半年我接了不少RoCE网络的排障和优化需求,有做存储的、有跑AI训练的,从100G到400G都有。说实话,大部分问题的根源不是网卡也不是交换机硬件性能,而是大家对RoCE这套机制“七分懂三分不懂”:知道要开PFC&#xff0c…

2026/10/7 10:30:42

JSP+Servlet+JDBC学生信息管理系统:分页搜索与CRUD实战

简介:面向Java Web课程设计与期末作业的学生信息管理系统项目包,涵盖登录验证、学生信息增删改查、课程关联等典型功能,适合正在学习Servlet/JSP、MVC分层架构与数据库编程的初学者。压缩包共209个文件,大小仅4.57MB,包…

2026/10/7 10:30:42

Android电子书阅读系统实战:SpringBoot后端与移动端全栈开发解析

1. 项目概述 接手这个基于Android的电子书阅读系统时,我的第一反应是:这又是一个典型的Java全栈毕业设计项目,后端SpringBoot负责业务逻辑,前端Android负责展示交互,再加一套完整的源码文档视频配套。但真正动手做完之…

2026/10/7 10:25:42

C#.NET大文件夹上传方案:分片上传与断点续传实战

直接切入正题。我接手过一个内部系统,需求描述很简短:“用户要把整个项目目录拖进网页里传上去,服务器上要能看到一模一样的文件夹结构。” 听起来跟平时传几个文件没啥区别,但做过上传功能的人都知道,这句话背后全是坑…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/7 8:18:33

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/6 17:46:51

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

2026/10/7 1:05:03

ESP32免重刷固件:浏览器直接修改NVS键值实现WiFi配置更新

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

2026/10/7 1:05:03

SAP HANA查询结果导出CSV:避开乱码、性能与权限的实用指南

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

2026/10/7 1:05:03

数字后端Placement阶段Density与Congestion控制实战

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑