Skip to content

fix: ignore CSI < and CSI = private parameter sequences#532

Merged
wyu71 merged 1 commit into
linuxdeepin:release/eaglefrom
wyu71:release/eagle
May 14, 2026
Merged

fix: ignore CSI < and CSI = private parameter sequences#532
wyu71 merged 1 commit into
linuxdeepin:release/eaglefrom
wyu71:release/eagle

Conversation

@wyu71
Copy link
Copy Markdown
Contributor

@wyu71 wyu71 commented May 14, 2026

Silently ignore unrecognized CSI sequences with < and = private parameter prefixes to prevent residual character output.

静默忽略未识别的带 < 和 = 私有参数前缀的 CSI 序列,
防止残留字符输出。

Log: 修复退出Claude Code时终端输出u字符的问题
PMS: BUG-356495
Influence: 修复后支持Kitty键盘协议的CSI <和CSI =序列,退出Claude Code等程序时不再有残留字符输出。

Silently ignore unrecognized CSI sequences with < and = private
parameter prefixes to prevent residual character output.

静默忽略未识别的带 < 和 = 私有参数前缀的 CSI 序列,
防止残留字符输出。

Log: 修复退出Claude Code时终端输出u字符的问题
PMS: BUG-356495
Influence: 修复后支持Kitty键盘协议的CSI <和CSI =序列,退出Claude Code等程序时不再有残留字符输出。
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的 Git Diff。本次修改的主要目的是在终端模拟器 Vt102Emulation 中增加对 CSI <CSI = 转义序列的静默忽略,以兼容如 Kitty 键盘协议等现代终端扩展。

整体而言,修改思路清晰,目的明确。但为了提升代码的一致性可读性健壮性,我提出以下改进意见:

1. 代码质量与可读性

问题:宏定义过长,且缺乏抽象
eps(C) 宏的修改中,条件判断越来越长,且 s[2] != '?' && s[2] != '!' && s[2] != '>' && s[2] != '<' && s[2] != '=' 这种排他逻辑非常难以阅读和维护。同时,receiveChar 函数中新增的 else if (p >= 3 && (s[2] == '<' || s[2] == '=')) 与上面已有的 egt() 等宏逻辑不统一。

改进建议:
仿照已有的 epp()epe()egt(),为新增的条件定义专门的宏,并将 eps(C) 中的排他逻辑替换为对这些新宏的排除。这样可以极大提升代码的可读性和一致性。

// 新增宏定义,与 epp(), epe(), egt() 保持风格一致
#define elt( )     (p >=  3  && s[2] == '<')
#define eeq( )     (p >=  3  && s[2] == '=')

// 优化 eps(C) 宏,使用新宏替代冗长的逻辑判断
#define eps(C)     (p >=  3  && !epp() && !epe() && !egt() && !elt() && !eeq() && cc < 256 && (charClass[cc] & (C)) == (C))

2. 语法逻辑与一致性

问题:处理逻辑的抽象层级不一致
receiveChar 函数的后半部分(处理 CSI 序列的地方),原代码使用了 egt() 这样的宏,而你新增的代码却使用了硬编码的底层判断 p >= 3 && (s[2] == '<' || s[2] == '=')

改进建议:
结合上面新增的宏,将硬编码替换为宏调用,保持代码抽象层级的一致性。同时,将 <= 拆分为两个独立的 else if 分支,这样如果未来需要对 <= 采取不同的处理策略(例如其中一个不再是被忽略的),修改起来更为方便和安全。

        else if (egt())
            processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
        else if (elt())
            ; // silently ignore CSI < sequences (e.g. Kitty keyboard pop)
        else if (eeq())
            ; // silently ignore CSI = sequences
        else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)

3. 代码性能

评价:性能无明显负面影响
在宏 eps(C) 中增加两个字符比较(s[2] != '<' && s[2] != '=')属于极低开销的整数比较操作,且由于短路求值特性,如果前面的条件不满足,后面的条件不会执行。在 receiveChar 这种高频调用的解析函数中,这种开销是可以忽略不计的。

4. 代码安全与健壮性

问题:数组越界风险(潜在)
在宏 eps(C) 以及 elt()eeq() 中,都有 p >= 3 的前置条件,这保证了访问 s[2] 时不会发生数组越界。这部分是安全的。

但是,我注意到原代码中存在一个隐患:宏 eec(C) 的定义是 (p >= 3 && cc == (C)),它没有检查 cc < 256,而 ees(C)eps(C) 都检查了 cc < 256。因为后续有 charClass[cc] 的操作,如果 cc 是宽字符(大于255),可能会导致 charClass 数组越界。虽然这不是本次修改引入的问题,但作为代码审查,建议在后续迭代中关注 charClass 的边界检查,确保 cc < 256cccharClass 数组的合法索引范围内。


综合修改建议代码

如果应用上述建议,你的 Diff 核心部分可以优化为如下形式:

// 宏定义区域修改
#define epp( )     (p >=  3  && s[2] == '?')
#define epe( )     (p >=  3  && s[2] == '!')
#define egt( )     (p >=  3  && s[2] == '>')
#define elt( )     (p >=  3  && s[2] == '<')  // 新增
#define eeq( )     (p >=  3  && s[2] == '=')  // 新增

// 使用逻辑非操作符优化 eps 宏
#define eps(C)     (p >=  3  && !epp() && !epe() && !egt() && !elt() && !eeq() && cc < 256 && (charClass[cc] & (C)) == (C))

// receiveChar 前置状态检查区域修改
    if (lec(3,2,'?')) { return; }
    if (lec(3,2,'>')) { return; }
    if (lec(3,2,'!')) { return; }
    if (lec(3,2,'<')) { return; }
    if (lec(3,2,'=')) { return; }

// receiveChar 后续 CSI 处理区域修改
        else if (egt())
            processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
        else if (elt())
            ; // silently ignore CSI < sequences (e.g. Kitty keyboard pop)
        else if (eeq())
            ; // silently ignore CSI = sequences
        else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)

这样的代码更符合该文件原有的设计模式,可维护性显著提高。希望这些建议对你有所帮助!

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, wyu71

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@wyu71 wyu71 merged commit 53a33ff into linuxdeepin:release/eagle May 14, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants