





















@@ -824,6 +824,50 @@ describe("marketplace plugins", () => {
824824});
825825});
826826827+it("rejects malformed archive content-length headers before streaming", async () => {
828+await withTempDir("openclaw-marketplace-test-", async (rootDir) => {
829+const reader = {
830+read: vi.fn(),
831+cancel: vi.fn(async () => undefined),
832+releaseLock: vi.fn(),
833+};
834+fetchWithSsrFGuardMock.mockResolvedValueOnce({
835+response: {
836+ok: true,
837+status: 200,
838+body: {
839+getReader: () => reader,
840+} as unknown as Response["body"],
841+headers: new Headers({ "content-length": "1e9" }),
842+} as unknown as Response,
843+finalUrl: "https://cdn.example.com/releases/frontend-design.tgz",
844+release: vi.fn(async () => undefined),
845+});
846+const manifestPath = await writeMarketplaceManifest(rootDir, {
847+plugins: [
848+{
849+name: "frontend-design",
850+source: "https://example.com/frontend-design.tgz",
851+},
852+],
853+});
854+855+const result = await installPluginFromMarketplace({
856+marketplace: manifestPath,
857+plugin: "frontend-design",
858+});
859+860+expect(result).toEqual({
861+ok: false,
862+error:
863+"failed to download https://example.com/frontend-design.tgz: " +
864+"invalid content-length header: 1e9",
865+});
866+expect(reader.read).not.toHaveBeenCalled();
867+expect(installPluginFromPathMock).not.toHaveBeenCalled();
868+});
869+});
870+827871it("cleans up a partial download temp dir when streaming the archive fails", async () => {
828872await withTempDir("openclaw-marketplace-test-", async (rootDir) => {
829873const beforeTempDirs = await listMarketplaceDownloadTempDirs();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。