Skip to content

Commit 938b2a8

Browse files
committed
fix: validate byteplus video duration metadata
1 parent 04c2982 commit 938b2a8

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

extensions/byteplus/video-generation-provider.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,42 @@ describe("byteplus video generation provider", () => {
177177
expect(requireBytePlusPostBody()).not.toHaveProperty("duration");
178178
});
179179

180+
it("drops malformed response duration metadata", async () => {
181+
postJsonRequestMock.mockResolvedValue({
182+
response: {
183+
json: async () => ({
184+
id: "task_123",
185+
}),
186+
},
187+
release: vi.fn(async () => {}),
188+
});
189+
fetchWithTimeoutMock
190+
.mockResolvedValueOnce({
191+
json: async () => ({
192+
id: "task_123",
193+
status: "succeeded",
194+
content: {
195+
video_url: "https://example.com/byteplus.mp4",
196+
},
197+
duration: 1.5,
198+
}),
199+
})
200+
.mockResolvedValueOnce({
201+
headers: new Headers({ "content-type": "video/mp4" }),
202+
arrayBuffer: async () => Buffer.from("mp4-bytes"),
203+
});
204+
205+
const provider = buildBytePlusVideoGenerationProvider();
206+
const result = await provider.generateVideo({
207+
provider: "byteplus",
208+
model: "seedance-1-0-lite-t2v-250428",
209+
prompt: "A lantern floats upward into the night sky",
210+
cfg: {},
211+
});
212+
213+
expect(result.metadata).toMatchObject({ duration: undefined });
214+
});
215+
180216
it("reports malformed create JSON with a provider-owned error", async () => {
181217
const release = vi.fn(async () => {});
182218
postJsonRequestMock.mockResolvedValue({

extensions/byteplus/video-generation-provider.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ function resolveBytePlusDurationSeconds(value: unknown): number | undefined {
137137
});
138138
}
139139

140+
function readBytePlusDurationSeconds(value: unknown): number | undefined {
141+
return asSafeIntegerInRange(value, {
142+
min: BYTEPLUS_MIN_DURATION_SECONDS,
143+
max: BYTEPLUS_MAX_DURATION_SECONDS,
144+
});
145+
}
146+
140147
async function pollBytePlusTask(params: {
141148
taskId: string;
142149
headers: Headers;
@@ -396,7 +403,7 @@ export function buildBytePlusVideoGenerationProvider(): VideoGenerationProvider
396403
videoUrl,
397404
ratio: normalizeOptionalString(completed.ratio),
398405
resolution: normalizeOptionalString(completed.resolution),
399-
duration: typeof completed.duration === "number" ? completed.duration : undefined,
406+
duration: readBytePlusDurationSeconds(completed.duration),
400407
},
401408
};
402409
} finally {

0 commit comments

Comments
 (0)