🔧 修复 Enlightenment E16 窗口管理器20年历史的Bug

来源: iczelia.net —HN 216 points

标签: Bug修复窗口管理器Newton算法C语言

📖 内容概述

一位出生于2004年的年轻开发者日常使用1997年的窗口管理器Enlightenment E16,在处理一个特定PDF时发现了桌面冻结的严重Bug。通过调试,她追踪到问题根源是E16文本渲染中一个存在了近20年的Newton算法实现缺陷。

🔍 问题根源分析

E16在渲染过长的窗口标题时使用"中间省略"算法——将长文本截断并在中间显示"..."。该算法使用Newton-style搜索来估计需要删除多少字符以适应宽度限制。

核心问题:Newton方法缺少迭代限制,导致在某些特定文本长度和宽度组合下陷入无限振荡。

代码中的缺陷

for (;;)  // 无迭代限制!
{
    // ... 计算nuke_count...
    
    if (nc2 >= 0 && nc2 < 3 * cw)
        break;  // 退出条件
    
    // Newton步进调整
    if (nc2 > 0)
        nuke_count -= ...;
    else
        nuke_count += ...;
}

🛠️ 修复方案

作者采用了三个防御性修改:

  1. 迭代次数上限: 添加32次迭代限制,超出后接受第一个可用的拟合结果
  2. nuke_count下限: 确保nuke_count至少为1,防止负数导致的头尾重叠
  3. cw下限: 将cw下限设为1,防止除零错误

💡 关键洞见

🔗 触发条件

任何WM_NAME足够长,导致中间省略搜索进入"overshoot regime"的窗口都会触发此Bug。实际案例:

"Kickoff.pdf — Introduction to Information Theory Session 1: kickoff & first topic"

(81个宽字符,~291px边框标题位)