@@ -7,6 +7,8 @@ const { fetchWithSsrFGuardMock } = vi.hoisted(() => ({
77 fetchWithSsrFGuardMock : vi . fn ( ) ,
88} ) ) ;
99
10+ const PROVIDER_RESPONSE_MAX_BYTES = 16 * 1024 * 1024 ;
11+
1012vi . mock ( "openclaw/plugin-sdk/ssrf-runtime" , ( ) => ( {
1113 fetchWithSsrFGuard : fetchWithSsrFGuardMock ,
1214} ) ) ;
@@ -45,6 +47,18 @@ function clearTtsEnv() {
4547 delete process . env . VOLCENGINE_TTS_TOKEN ;
4648}
4749
50+ function makeOversizedStreamResponse ( ) : Response {
51+ return new Response (
52+ new ReadableStream < Uint8Array > ( {
53+ start ( controller ) {
54+ controller . enqueue ( new Uint8Array ( PROVIDER_RESPONSE_MAX_BYTES ) ) ;
55+ controller . enqueue ( new Uint8Array ( 1 ) ) ;
56+ controller . close ( ) ;
57+ } ,
58+ } ) ,
59+ ) ;
60+ }
61+
4862function restoreOptionalEnv ( key : string , value : string | undefined ) {
4963 if ( value === undefined ) {
5064 delete process . env [ key ] ;
@@ -301,6 +315,23 @@ describe("volcengineTTS", () => {
301315 expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
302316 } ) ;
303317
318+ it ( "bounds Seed Speech success response reads" , async ( ) => {
319+ const release = vi . fn ( ) ;
320+ fetchWithSsrFGuardMock . mockResolvedValue ( {
321+ response : makeOversizedStreamResponse ( ) ,
322+ release,
323+ } ) ;
324+
325+ await expect (
326+ volcengineTTS ( {
327+ text : "hello" ,
328+ apiKey : "secret-api-key" ,
329+ timeoutMs : 1000 ,
330+ } ) ,
331+ ) . rejects . toThrow ( "BytePlus Seed Speech TTS response exceeds 16777216 bytes" ) ;
332+ expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
333+ } ) ;
334+
304335 it ( "reports provider errors without exposing credentials" , async ( ) => {
305336 const release = vi . fn ( ) ;
306337 fetchWithSsrFGuardMock . mockResolvedValue ( {
@@ -327,4 +358,22 @@ describe("volcengineTTS", () => {
327358 expect ( ( error as Error ) . message ) . not . toContain ( "secret-token" ) ;
328359 expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
329360 } ) ;
361+
362+ it ( "bounds legacy Volcengine success response reads" , async ( ) => {
363+ const release = vi . fn ( ) ;
364+ fetchWithSsrFGuardMock . mockResolvedValue ( {
365+ response : makeOversizedStreamResponse ( ) ,
366+ release,
367+ } ) ;
368+
369+ await expect (
370+ volcengineTTS ( {
371+ text : "hello" ,
372+ appId : "app-id" ,
373+ token : "secret-token" ,
374+ timeoutMs : 1000 ,
375+ } ) ,
376+ ) . rejects . toThrow ( "Volcengine TTS response exceeds 16777216 bytes" ) ;
377+ expect ( release ) . toHaveBeenCalledTimes ( 1 ) ;
378+ } ) ;
330379} ) ;
0 commit comments