

























@@ -179,7 +179,8 @@ describe("transitive-manifest-risk-report", () => {
179179});
180180181181it("fetches full npm packuments for the requested manifest version", async () => {
182-const fetchCalls: Array<{ url: string; accept: string | null }> = [];
182+const fetchCalls: Array<{ url: string; accept: string | null; signal: AbortSignal | null }> =
183+[];
183184const manifest = await fetchNpmManifest({
184185packageName: "@scope/package",
185186version: "1.0.0",
@@ -188,6 +189,7 @@ describe("transitive-manifest-risk-report", () => {
188189fetchCalls.push({
189190url: String(url),
190191accept: new Headers(init?.headers).get("accept"),
192+signal: init?.signal instanceof AbortSignal ? init.signal : null,
191193});
192194return new Response(
193195JSON.stringify({
@@ -216,6 +218,7 @@ describe("transitive-manifest-risk-report", () => {
216218{
217219url: "https://registry.example.test/@scope%2fpackage",
218220accept: "application/json",
221+signal: expect.any(AbortSignal),
219222},
220223]);
221224expect(manifest).toEqual({
@@ -231,6 +234,37 @@ describe("transitive-manifest-risk-report", () => {
231234});
232235});
233236237+it("cancels stalled npm registry body reads when the request aborts", async () => {
238+const controller = new AbortController();
239+let canceled = false;
240+const response = {
241+headers: new Headers(),
242+body: {
243+getReader() {
244+return {
245+read() {
246+return new Promise<ReadableStreamReadResult<Uint8Array>>(() => {});
247+},
248+async cancel() {
249+canceled = true;
250+},
251+releaseLock() {
252+throw new Error("releaseLock should not run while a read is pending");
253+},
254+};
255+},
256+},
257+} as unknown as Response;
258+259+const readPromise = readBoundedNpmRegistryText(response, 8, {
260+signal: controller.signal,
261+});
262+controller.abort(new Error("npm registry request timed out"));
263+264+await expect(readPromise).rejects.toThrow("npm registry request timed out");
265+expect(canceled).toBe(true);
266+});
267+234268it("rejects npm registry bodies that exceed the content-length cap", async () => {
235269let canceled = false;
236270const response = new Response(
@@ -247,7 +281,7 @@ describe("transitive-manifest-risk-report", () => {
247281);
248282249283await expect(readBoundedNpmRegistryText(response, 8)).rejects.toThrow(
250-"npm registry response exceeded 8 bytes (content-length 12)",
284+"npm registry response exceeded 8 bytes",
251285);
252286expect(canceled).toBe(true);
253287});
@@ -260,7 +294,7 @@ describe("transitive-manifest-risk-report", () => {
260294});
261295262296await expect(readBoundedNpmRegistryText(response, 8)).rejects.toThrow(
263-"npm registry response exceeded 8 bytes (content-length 12)",
297+"npm registry response exceeded 8 bytes",
264298);
265299});
266300@@ -306,7 +340,7 @@ describe("transitive-manifest-risk-report", () => {
306340);
307341308342await expect(readBoundedNpmRegistryText(response, 8)).rejects.toThrow(
309-"npm registry response exceeded 8 bytes while reading response body",
343+"npm registry response exceeded 8 bytes",
310344);
311345});
312346});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。