Files
drouter/packaging
liuzhuohua d0a72bbb5f fix(release): Release 附件版本号单一真源 + 堵住「注释掉整行代码」型注入残留
发 v1.0.9 前发现两个真问题,都会直接影响用户拿到的附件。

一、docker-compose.yml 里的镜像标签是硬编码的 1.0.8

这两个文件是**直接挂到 GitHub Release 上的附件**,用户照着抄命令。
早先它们硬编码具体版本号,每次发版要人工 sed 一遍 —— 这次就漏了:
附件里写着 `image: drouter:1.0.8`,而镜像 tar 加载后的标签是 `drouter:1.0.9`,
`docker compose up` 直接报「找不到镜像」。DOCKER-GUIDE.md 另有 14 处同样问题。

改成 __VERSION__ 模板,由 build-docker.sh 渲染(版本从 packaging/VERSION 读)。
渲染分两步,顺序不能反:先删 TEMPLATE-NOTE 标记块(那是给维护者看的
「这是模板」提示,留着用户会看到「1.0.9 是占位符」这种自相矛盾的话),
再替换占位符。先替换的话,标记块里的 __VERSION__ 也会被换掉。

retag-docker-image.py 同样问题:NEW_TAGS 硬编码。改完参数化。
这个 bug 更隐蔽 —— 拿 1.0.9 的镜像跑重标记会打上 1.0.8 的标签,
用户 load 完看到的标签与附件说明对不上。

t-packaging.py 补 12 条判据卡住这些(4 条已做反向验证:注入即红、还原即绿)。
判据只抓「紧挨 drouter 标识或产物文件名」的版本号 —— 一刀切拦所有 x.y 会
误伤「1.0.1 起 Web 终端绕开 init」这种历史沿革说明和「GPL-3.0」许可证名。

二、t-worktree-clean.py 抓不到「注释掉整行代码」型注入

跑回归时 t-107 红了 1 项,查出来是 t-107-inject-wg.py 把
`'env': _vpn_env(),` 注释掉了没还原(SIGTERM 打断,finally 没执行)——
和 v1.0.8 那次 `/nonexistent` 残留一模一样的坑,但**形态不同**:
不含任何哨兵字样,原判据的 4 个哨兵全都抓不到。

后果很实:_vpn_status 不返回 env,前端拿不到四态诊断,
VPN 页面的三个修复按钮全废。这正是 v1.0.8 声称修好的那个 bug。

补两条判据:
- 扫「被注释掉的整行代码」:去掉 # 后能 ast.parse 成功,且含调用/赋值/return/dict 项
- 扫 CRLF:Windows 工具写文件会整篇改行尾,sync.sh 预检才拦太晚

判据本身踩了三个坑,都记在注释里:
- dict 项 `'env': _vpn_env(),` 单独 ast.parse 会 SyntaxError(没大括号),
  真正的注入反而被放过 → 补大括号再解析
- dict 项的键**通常带引号**,正则只写 ^[A-Za-z_] 认不出来 → 改成同时认引号键
- 分隔线注释 `# ------ radvd` 里的 ----- 会被解析成负号表达式 → 按前缀排掉

双向验证:4 种注入形态(赋值/dict项/bool/列表)全部精确报到行号,
基线零误报(排掉了分隔线注释和「# module: (service, action, 中文名)」这类
长得像 dict 项的文档注释)。

三、_dev/dl-verify.py(新增)

从目标机往 Windows 拉大产物时发现的坑,记成脚本省得下次重踩:
- `ssh host 'cat f' > out` 在 Windows 上做**文本模式换行转换**,二进制被破坏
  (实测 deb 少 4 字节,sha256 直接对不上)→ 走 base64 再本地解码
- Windows Python 看不到 Git Bash 的 /tmp,必须给 C:/ 绝对路径
- scp 传完一定要判 sha256 —— scp/ssh 都可能「返回 0 却落地 0 字节」
- 落地走 .part + os.replace,避免写一半失败留下半个产物

顺带修了 build-docker.sh 里一处路径笔误
(packaging/docker/packaging/docker/DOCKER-GUIDE.md)和步骤编号 1/3→1/4。
2026-10-04 14:05:33 +08:00
..