Skip to content

Commit 13be16d

Browse files
committed
fix(openai): cancel oversized Codex image streams
1 parent 257b533 commit 13be16d

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

extensions/openai/image-generation-provider.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,42 @@ describe("openai image generation provider", () => {
10011001
});
10021002
});
10031003

1004+
it("cancels oversized Codex OAuth image response streams", async () => {
1005+
mockCodexAuthOnly();
1006+
let canceled = false;
1007+
let chunkSent = false;
1008+
const release = vi.fn(async () => {});
1009+
const stream = new ReadableStream<Uint8Array>({
1010+
pull(controller) {
1011+
if (chunkSent) {
1012+
return;
1013+
}
1014+
chunkSent = true;
1015+
controller.enqueue(new Uint8Array(64 * 1024 * 1024 + 1));
1016+
},
1017+
cancel() {
1018+
canceled = true;
1019+
},
1020+
});
1021+
postJsonRequestMock.mockResolvedValue({
1022+
response: new Response(stream),
1023+
release,
1024+
});
1025+
1026+
const provider = buildOpenAIImageGenerationProvider();
1027+
await expect(
1028+
provider.generateImage({
1029+
provider: "openai",
1030+
model: "gpt-image-2",
1031+
prompt: "Draw an oversized Codex lighthouse",
1032+
cfg: {},
1033+
authStore: createCodexOAuthAuthStore(),
1034+
}),
1035+
).rejects.toThrow("OpenAI Codex image generation response exceeded size limit");
1036+
expect(canceled).toBe(true);
1037+
expect(release).toHaveBeenCalledTimes(1);
1038+
});
1039+
10041040
it("does not treat Codex API key profiles as configured Codex OAuth image auth", async () => {
10051041
mockGeneratedPngResponse();
10061042
resolveApiKeyForProviderMock.mockImplementation(async (params?: { provider?: string }) => {

extensions/openai/image-generation-provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ async function readResponseBodyText(response: Response): Promise<string> {
506506
if (value) {
507507
byteLength += value.byteLength;
508508
if (byteLength > MAX_CODEX_IMAGE_SSE_BYTES) {
509+
await reader.cancel().catch(() => undefined);
509510
throw new Error("OpenAI Codex image generation response exceeded size limit");
510511
}
511512
chunks.push(decoder.decode(value, { stream: !done }));

0 commit comments

Comments
 (0)