Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/app/service/content/gm_api/gm_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,53 @@ return { value1, value2, value3, values1,values2, allValues1, allValues2, value4
});
});

describe("@grant GM_download", () => {
it("空 url 应触发 onerror 而不是发起下载(GM_download)", async () => {
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
script.metadata.grant = ["GM_download"];
const exec = new ExecScript(script, {
envPrefix: "scripting",
message: undefined as any,
contentMsg: undefined as any,
code: nilFn,
envInfo,
});
script.code = `return new Promise((resolve) => {
let onloadCalled = false;
GM_download({
url: "",
name: "empty-url-test.bin",
onload: () => { onloadCalled = true; },
onerror: (e) => resolve({ onloadCalled, error: e && e.error }),
});
setTimeout(() => resolve({ onloadCalled, error: "TIMEOUT" }), 100);
})`;
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
expect(ret.onloadCalled).toEqual(false);
expect(ret.error).toEqual("unknown");
});

it("空 url 应 reject(GM.download)", async () => {
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
script.metadata.grant = ["GM.download"];
const exec = new ExecScript(script, {
envPrefix: "scripting",
message: undefined as any,
contentMsg: undefined as any,
code: nilFn,
envInfo,
});
script.code = `return GM.download({ url: "", name: "empty-url-test.bin" }).then(
() => ({ resolved: true }),
() => ({ resolved: false })
)`;
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
expect(ret.resolved).toEqual(false);
});
});

describe("@grant CAT.agent.conversation", () => {
it("CAT.agent.conversation 应该在沙盒中可访问", async () => {
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
Expand Down
9 changes: 9 additions & 0 deletions src/app/service/content/gm_api/gm_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,15 @@ export default class GMApi extends GM_Base {
};
const handle = async () => {
const url = await urlPromiseLike;
if (!url) {
// TM 对空 url 会同步报错/触发 onerror,而非发起请求;
// new URL("", base) 不会抛错而是解析为当前页面地址,因此需在此显式拦截,避免误下载当前页面。
if (!aborted) {
details.onerror?.(makeCallbackParam({ error: "unknown" }) as GMTypes.DownloadError);
retPromiseReject?.(new Error("GM_download: url is empty"));
}
return;
}
const downloadMode = details.downloadMode || "native"; // native = sc_default; browser = chrome api
details.url = url;
if (downloadMode === "browser" || url.startsWith("blob:")) {
Expand Down
Loading