修复
- mp4box 混流临时产物扩展名兼容性:混流事务化的临时输出名
.muxing-{guid}为未知扩展名,mp4box(GPAC)按扩展名推断输出封装格式,新版 filter-based MP4Box 上行为随版本而异(可能告警回退甚至失败)。现临时名以.mp4结尾,新旧版本全部确定性走 ISOM 封装(ffmpeg 分支本就用-f mp4强制格式,不受影响)。 - 多线程下载遇不支持 Range 的服务器时整批中止:多线程分片路径在服务器以 200 响应 Range 请求时抛出的
NotSupportedException(及其它白名单外异常)会穿透页面级与批级两级 catch 过滤器,导致多 P 批量中一 P 命中即放弃剩余分 P、丢失完成通知与失败汇总。现抛出点规范化为InvalidOperationException并将过滤器补齐AggregateException。 - SubOnly 模式 ASS 字幕产物扩展名错误:ASS 内容字幕被无条件改名为
.srt,播放器无法渲染。现按源字幕内容形态决定目标扩展名。 <publishDate:...>/<videoDate:...>占位符在特定区域设置下产出非法文件名:自定义日期格式的:是时间分隔符占位符,fi-FI 等区域下输出形如22.13,en-US 下输出含:(Windows 上可写入 NTFS 备用数据流,资源管理器不可见)。现固定 InvariantCulture 格式化并对替换值做文件名净化(与 ffmpegcreation_time的收口同构)。- 重跑已下载视频时封面/装饰文件残留:混流锁内权威跳过分支漏删封面文件(每次残留一张且 aid 目录永远非空);DASH 分支跳过路径的多处裸
File.Delete/Directory.Delete在文件恰被杀软/索引器持有时抛 IOException,把"已下载成功"翻成整页失败重试。现已与 FLV 分支对齐统一包裹清理。 - serve 交互式选项导致任务不可取消地占死并发槽:客户端经 API 提交
{"interactive":true}会让任务阻塞在Console.ReadLine——不可被取消中断,少量任务即可占满--max-concurrent直至进程重启。现 serve 下强制关闭交互式模式。 - 特定区域设置下视频发布时间元数据丢失:ffmpeg
creation_time时间戳的自定义格式未固定文化,:在 fi-FI 等区域设置下被解析为时间分隔符占位符(产出形如19.30.00的非 ISO-8601 串),av_parse_time解析失败后元数据静默丢失。现追加CultureInfo.InvariantCulture。 - 杜比视界自动切 mp4box 时封面静默丢失:
-itags的cover值(本地封面路径)未按 mp4box itags 值转义规则处理,Windows 路径中的\被当转义序列消费。现与同函数其它 itags 值一致走EscapeString。 - 配置文件 URL 被 URL 形值的命令行选项误压制:
BBDown.config中写了下载 URL、命令行又恰好携带值形似 URL 的选项(如--aria2c-proxy http://127.0.0.1:7890、--work-dir av123)时,配置里的 URL 被误判"命令行已给出"而丢弃,Spectre 报缺少必填参数。现仅对位置参数应用 URL 启发式(选项值不再参与判定)。 - FLV 跳过下载路径残留临时元数据文件:FLV 跳过路径未清理封面、字幕与章节文件,且章节清理此前仅匹配固定名
chapters而未覆盖 muxer 产出的唯一名chapters-{basename}。现与 DASH 分支行为对齐并在跳过/失败路径按chapters*前缀兜底清理。 - serve 已完成任务溢出裁剪按完成顺序误删:
finishedTasks按完成时间追加,旧逻辑直接移除列表头部会误删"后创建但先完成"的任务。现改为按TaskCreateTime排序裁剪最旧创建的任务。 - Parser 大会员回退硬编码域名与子串匹配脆弱:番剧大会员回退网页源硬编码
www.bilibili.com(忽略EpHost镜像配置);大会员错误判定依赖裸子串\"大会员专享限制\"易受文案漂移影响。现 host 跟随配置,判定优先解析 JSON 根message字段。 BaseUrlRegex贪婪匹配误判 query 为端口:原正则http.*:\d+会将http://host/path?x=1:2中 query 的:数字误判为端口。现收紧为^https?://[^/:]+:\d+。
改进
- serve API 响应与持久化健壮性:
/get-tasks族响应补Cache-Control: no-store与X-Content-Type-Options: nosniff(任务数据含服务器绝对路径,禁止缓存落盘),认证限速与查询限速的 429 响应补Retry-After: 60;任务持久化临时文件名带 GUID(对齐订阅历史,同目录多实例不再互相踩踏写盘);同一产物不再在任务快照中重复记录(AddSavePath去重)。 - wiki 同步脚本健壮化:
scripts/sync-wiki.ps1检查 git 命令退出码(此前 commit 失败仍报成功)、自动清理 wiki 上源目录已删除的页面、异常时恢复调用目录。 - 进程与解析层健壮性:直播杜比视界的 ffmpeg 版本探测改真异步(不再在下载链路同步阻塞最多 5 秒,超时后补观察管道任务);用户取消(Ctrl+C/关停)不再被解析层"免二压重发"降级路径吞掉;免二压降级路径下杜比/Hi-Res 音轨不再重复追加;番剧 gRPC 移除与目标主机不符的硬编码 Host 头;收藏夹翻页遇空页提前结束(防畸形 media_count 触发请求洪泛);国际版番剧接口删除多余的双重转义替换;登录轮询的重定向跳数上限改为确定性失败(不再误触发整流程重试)。
- 文档修正:wiki 退出码表删除虚构的
2/3退出码并修正 Ctrl+C 归属(主命令实际返回 130、子命令 0、工具缺失归 1);参数总表补--host/--ep-host/--tv-host/--area;README serve 配置注入说明补全选项列举。 - CLI 命令层全量迁移
AsyncCommand:login/logintv/article/live/sub check/watchlater/serve7 个命令不再以Task.Run + GetAwaiter().GetResult()阻塞线程池线程等待异步操作(serve 长驻进程此前整个生命周期额外占用 1 个阻塞线程);serve 链路改为真异步(RunAsync/StartServerAsync),监听地址前置校验独立为ValidateListenUrl。各命令退出码与错误语义不变。
安全性
- serve 无 token 模式 DNS rebinding 防线:浏览器同源 GET 不携带 Origin,写端点的 Origin 校验保护不到读端点——攻击者网页经 rebinding(攻击者域名解析到 127.0.0.1)可读取
/get-tasks*响应中的任务数据(含服务器绝对路径)。现无 token 时强制 Host 头为字面回环(localhost/127.0.0.0/8/::1,不做 DNS 解析),携带 token 的反代/自定义域名部署不受影响。 - aria2c 输入换行注入面收口:aria2c input-file 语法中换行即指令行分隔符,来自 API 响应的 URL 与用户配置的 Cookie 未剥离 CR/LF 时可注入任意 aria2c 指令行(新 URI/
all-proxy/dir等)。现写入 stdin 前剥离换行。 - 服务器可控文本不再直拼文件路径:字幕语言代码(
lan)、音频 ID(audio_id)来自接口响应(镜像站/--insecure属项目威胁模型内的对抗源),含..\时可写出工作目录。现统一经GetValidFileName净化后再拼路径。 - HTTP 响应体大小上限:gzip 解压侧已有 48MB 上限,但压缩响应体本体与普通响应体无上限,被攻破端点或
--insecure中间人可用巨包/分块慢发响应耗尽进程内存。现统一 64MB 上限(Content-Length 预检 + 逐块累计双拦截)。 - serve 日志注入残留收口:解析失败日志两处原始
option.Url未单行化,客户端可借请求体 URL 中的 CR/LF 伪造日志行。现统一过SanitizeLogString。 - Widevine 许可证请求禁跟随重定向:许可证 POST 的请求体是设备私钥签名的 challenge,原
VerifiedAppHttpClient(允许自动重定向)会在 307/308 上连同 body 重放到跨主机目标。新增VerifiedNoRedirectClient(始终校验证书 + 禁自动重定向,独立连接池不受--insecure降级),3xx 显式报错不跟随(与 gRPC POST 的凭据收口同构)。 - serve 认证失败限速字典有界裁剪:防止攻击者使用大量独立 IP 或伪造 XFF 标头导致限速记录字典无界增长,在超过上限
MaxTrackedAuthFailureIps时按最后失败时间自动裁剪,保留最近活跃记录。 - 登录轮询跟随重定向逐跳可信主机校验:
GetWebSourceWithSetCookiesAsync切换为禁自动跳转客户端手动逐跳,每跳发起前校验IsTrustedCookieHost,防止重定向将用户凭证及下发的Set-Cookie泄露至不可信主机。
测试增强
- 全库测试 666 例(新增 7 例):serve Host 白名单端点行为(evil Host 403/回环放行/带 token 跳过校验)与纯函数判定、aria2c stdin 单行化、日期占位符文化无关与路径净化(fi-FI 区域下断言)、HTTP 响应体上限判定、serve Interactive 清零等。
- 此前批次(659 例,新增 25 例):VerifiedNoRedirectClient 身份稳定性、GET/POST 307 不跟随、配置合并 URL 形值选项回归、章节前缀清理、认证字典限速有界裁剪、已完成任务溢出按创建时间排序、大会员 JSON message 字段解析、BaseUrlRegex 严格匹配、登录轮询逐跳重定向安全拦截与合法跟随等。
Commits
- release: 发布 v1.6.17——第 12 轮审查消纳(管线过滤器/rebinding 防线/路径净化/混流兼容性/文档修正)
- fix: RF-23 混流临时名补 .mp4 后缀 + 消纳 Info 级观察 8 项
- fix: 消纳第 12 轮审查发现 RF-14~RF-29
- docs: REVIEW_PLAN 第 12 轮记录、REVIEW_FINDINGS RF-14~RF-29 登记、新增 fork 与上游差异文档
- docs: REVIEW_PLAN 第 11 轮记录、REVIEW_FINDINGS RF-8~RF-13 结转、CHANGELOG 未发布条目
- fix(core): RF-11 大会员回退适配镜像站与 JSON 解析、RF-12 正则收紧、RF-13 登录轮询逐跳校验
- fix(serve): RF-9 认证失败字典有界裁剪、RF-10 已完成任务溢出按创建时间排序
- fix(download): RF-8 FLV 跳过路径补充清理未消费元数据文件、章节按前缀兜底清理
- docs: REVIEW_PLAN 第 10 轮记录、REVIEW_FINDINGS RF-2 结转、CHANGELOG 未发布改进条目
- refactor(cli): RF-2 命令层一次性批量迁移 AsyncCommand
- docs: REVIEW_PLAN 第 9 轮记录、REVIEW_FINDINGS RF-4~RF-7 状态结转、CHANGELOG 未发布条目
- fix(config): RF-7 cliHasUrl 只对位置参数应用 URL 启发式
- fix(drm): RF-4 许可证请求切换 VerifiedNoRedirectClient 并显式拦截 3xx
- fix(muxer): RF-5 creation_time 固定 InvariantCulture、RF-6 mp4box cover 值补 EscapeString
- docs: REVIEW_PLAN 第 8 轮续审记录与 REVIEW_FINDINGS 新增 RF-5~RF-7
- test(parser): 新增 ExtractTracksAsync 夹具回放护栏(FakeBilibiliApiServer + 14 场景)
- refactor(core): UGC web playurl 主机引用 Config.Host 并使 API 前缀感知 scheme
- docs: 补 --trusted-proxy 与 BBDOWN_SERVE_TOKEN 用户文档并修正环境变量表述
- docs: 新增维护计划——Parser 护栏测试与 serve 安全选项文档同步
- docs: 新增 AGENTS.md 代理协作指引
- fix(core): 凭据门收口、文化不变解析与截断误报修正
- fix(live): 丢弃不足完整 FLV 头的垃圾段;live/article 相对输出落 work-dir
- fix(download): 只读模式删目录加空守卫并清理 .merging 残留
- fix(muxer): mp4box 分支编入配音/背景音轨并统一工具缺失异常类型
Downloads
| Platform | Architecture |
|---|---|
| Windows | x64, arm64 |
| Linux | x64, arm64 |
| macOS | x64, arm64 |
Full Changelog: v1.6.16...v1.6.17