🐛 修复 GM_download 传入空 url 时未触发 onerror 的兼容性问题#1619
Open
cyfung1031 wants to merge 2 commits into
Open
Conversation
new URL("", location.href) 不会抛错而是解析为当前页面地址,导致空 url
被当作有效地址发起下载,与 TM 触发 onerror 的行为不一致。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
背景
GM_download传入空字符串url时,ScriptCat 与 Tampermonkey 行为不一致:TM 会同步报错或触发onerror;ScriptCat 既不抛错也不触发onerror,而是触发onload。根因:
src/app/service/content/gm_api/gm_xhr.ts中new URL(urlResolved, window.location.href)对空字符串不会抛错,而是按 WHATWG URL 规范解析为当前页面自身的地址。_GM_download的handle()在此之前没有对空url做拦截,导致空 url 被当作合法地址,静默对当前页面发起"下载"请求并触发onload。复现脚本见 #1618(仅用于该 issue/本 PR 的说明,未加入自动化测试用例)。
本次改动
src/app/service/content/gm_api/gm_api.ts:在_GM_download的handle()内,await urlPromiseLike得到url后立即校验;url为空时直接触发details.onerror?.({ error: "unknown" })并 rejectretPromise,不再进入browser/native下载分支。该校验位于downloadMode分支之前,因此同时覆盖native与browser两种模式。src/app/service/content/gm_api/gm_api.test.ts:新增@grant GM_download用例,分别验证GM_download(回调形式)触发onerror且不触发onload,以及GM.download(Promise 形式)会 reject。已知限制
example/tests/gm_download_test.js已覆盖空 url 场景的手动/E2E 测试,本次未新增额外的手动测试脚本(按要求)。src/app/service/service_worker/gm_api/gm_api.ts中browserdownloadMode 下的空 url 兜底分支(发送data: null的onerror)仍保留原状,未做改动;该分支在本次修复后不再是空 url 场景下唯一的兜底路径,但作为纵深防御原样保留,属既有代码,不在本次改动范围内。建议审查重点
_GM_download中新增的空 url 判断是否会误伤合法但"假值"的 url(例如url经convObjectToURL转换 Blob/File 后是否可能为空字符串)——convObjectToURL产出的应始终是非空的blob:/data URL,故不受影响。error: "unknown"是否是合适的错误码选择:GMTypes.DownloadError.error的取值中没有专门的"url 为空/不合法"错误码,unknown与本文件其余兜底错误路径(如后台连接失败、onMessage收到onerror)保持一致。关联
Fixes #1618
验证
pnpm vitest run src/app/service/content/gm_api/gm_api.test.ts src/app/service/service_worker/gm_api/gm_api.test.ts— 54 passedgit stash掉实现改动后重跑新增用例,两条用例均按预期失败(onerror未触发 /GM.download超时未 reject),证明用例确实覆盖了该缺陷。pnpm exec tsc --noEmit -p tsconfig.json— 无输出,通过pnpm exec eslint src/app/service/content/gm_api/gm_api.ts src/app/service/content/gm_api/gm_api.test.ts— 无输出,通过