home // archives // atom // rss

两段式兔子洞

posted: 2023-12-31 23:59

modified: 2024-01-01 00:48

上个月的某天, ArchCN Telegram 群里出现一条不雅发言。我以为又是一个新来的 spambot,作为管理员自然就顺手选择了 ban + report + delete all 三连套餐。结果 q234rty 提醒我,这并不是 spambot,甚至也不是新人,而是早已在群内有发言的群友,所以我的 delete all 操作删除了他的大量历史发言记录。

Telegram 一直存在一个缺点,就是已经发表了好久的消息也可以被自己或被管理员批量删除,且删除的消息无法恢复(只能由管理员在回收站里临时看两天)。而 ArchCN 群是主张保留所有聊天记录的,再配合 落絮 的索引和查询功能来给未来的群友提供参考资料。

我的这次不慎的批量删除对聊天记录造成了破坏,而造成这种「手滑」的原因,除了我自己面对不雅发言太着急操作以外,还有就是 Telegram 客户端对于批量删除的警示不够明显,只是在勾选 delete all 时把消息总数显示在删除键的括号里。

Telegram 提示: Delete (9)

给 Telegram 增加批量删除警告

好在 Telegram 至少还有一个优点:客户端是开源的。既然使用遇到了问题,那当然就应该自己动手解决。 它在 GNU/Linux 桌面上的 客户端 使用的是 C++/Qt,按道理这是我非常熟悉的语言和框架,但它在 Qt 之上又自己包了一层图形界面库 libui 。使用这个库写出来的程序长得不太像一般的 C++,倒是有浓烈的函数式风格,有些像 haskell / kotlin 了。

经过大约一天的搏斗,总算是成功加上了一个警告框。尤其是我暂时只能使用一台内存只有 16GB 的笔记本来编译,拖慢了不少进度。 然而测试时我才发现更大的问题:它这个括号里的消息总数是从服务器那边获取的,所以如果手快的话,它是来不及显示出来的。甚至它的消息计数是有滞后的,刚刚发送的消息可能不会被统计进去。经过试验,最高可能有几分钟的延迟!这样一来,原本计划的「消息总数超过3条再触发警告」也行不通了,因为刚刚发送的消息可能没有计入这个数字嘛。我只好干脆改成了无论消息总数是多少,一律弹出这个警告框。

Telegram 提示: Warning! You're deleting at least 9 messages in total

经过本地编译打包确认它工作无误后,我打算它制作成 源码补丁 发送给依云(lilydjwg)以便进入 archlinuxcn 源中的 telegram-desktop-lily 包进行分发。(我知道 Telegram 官方是一定不会接受这种补丁的。)这时,意想不到的事情出现了……

从天而降的 vim bug

由于我是在发布版本(而非 git 版本)的 telegram 源码上进行修改的,所以我没有使用熟悉的 git diff 命令来产生补丁,而是使用了 diff -Naur 命令。然后我就使用 vim 来编辑一下产生的补丁文件,把无关的改动去除……等下,这是怎么了?

vim: E315: ml_get: Invalid lnum: 600

怎么 vim 还能被我遇到 bug 的,要知道我可是除了 :wq a i 之外就不会几个命令的纯小白…… 我以为只是偶发事件,先忽略它把补丁文件发给依云了。可是在我用 vim 编辑某个 .cpp 文件的时候,这个错误也会时不时跳出来。依云也鼓励我去报 bug,于是我就开始研究如何复现它。

我发现在 Telegram 的某个 .cpp 文件里面跳转到中间某处,再删除很多行,再使用 Page Down 来滚动很多行,比较容易发生这个错误。在排除了我自己的 vimrc 带来的影响后,我提取了这个 .cpp 文件的一部分,在里面使用 vim 的 来重复一些命令。然而它似乎并不是每次都能复现错误,甚至执行同一个宏的结果都可能有很大不同……

这时候我以为是我的终端窗口大小等因素对复现错误有影响,可是我固定它的大小为 80×24 后还是不能稳定复现。最后我发觉似乎是我的 vim 录制宏的功能随着它一起坏掉了,导致我每次执行的命令序列其实不一样,看起来就像无法稳定复现。随后我就改用手输入确定的命令,并改变其中的滚动行数等,过不久就试验出了稳定的复现方法,并发送了 bug 报告。如果你想知道具体的重现步骤和错误,可以直接查看该报告。我本打算接下来继续 debug vim,但无奈因为我实在是太不熟悉它的术语了,在浏览源码时感到十分困难,就放弃继续自己 debug,把这部分工作交给 vim 开发者了。好在仅仅两天后,就有开发者提供了修复方法,并在四天后合并进了主线。现在包含该补丁的版本已经进入 Arch Linux 等发行版的仓库了。

总结

兔子洞,英文称 Down the rabbit hole ,出自《 爱丽丝梦游奇境记 》的开头,即爱丽丝追随一只兔子掉进一条长长的、看不到尽头的兔子洞。下图为我拍摄的某兔子洞。现在这个短语也用来形容在虚拟世界里顺着一环一环的线索,逐渐偏离了最初的目标而来到了未曾设想的地方。 这次带我进洞的兔子就是那句不雅消息,然而却意外给 Telegram 客户端新增了一个小功能,还给 vim 提了一个 bug。我以前以为 vim 这么成熟的软件,我又不是正经使用 vim 的用户,应该永远轮不到我来报告 bug 的呢。这也是我在2023年里最意外的自由软件贡献。

图片:草地上的兔子洞,有四个入口

上一篇还是2021年,随后就是最魔幻的2022年(我是上海居民……)。 如今转眼2023年都要结束了,为了防止本blog又要开一年的天窗,特此记录。希望下一篇不要隔得这样久……


© oldherl. built using python and pelican. theme inspired by nord.