@@ -84,4 +84,58 @@ return Math.random()
8484 ) ;
8585}
8686
87+ {
88+ const started = Date . now ( ) ;
89+ await assert . rejects (
90+ ( ) =>
91+ runWorkflowSandbox ( {
92+ parsed : parseWorkflowScript ( `
93+ export const meta = { name: 'sync-loop', description: 'd' }
94+ while (true) {}
95+ ` ) ,
96+ api : api ( { name : "sync-loop" , description : "d" } ) ,
97+ timeoutMs : 100 ,
98+ } ) ,
99+ / e x c e e d e d h o s t t i m e o u t / ,
100+ ) ;
101+ assert . ok ( Date . now ( ) - started < 5_000 , "synchronous loop should be externally terminated" ) ;
102+
103+ const followup = parseWorkflowScript ( `
104+ export const meta = { name: 'after-loop', description: 'd' }
105+ return 'still-alive'
106+ ` ) ;
107+ assert . equal (
108+ await runWorkflowSandbox ( { parsed : followup , api : api ( followup . meta ) } ) ,
109+ "still-alive" ,
110+ ) ;
111+ }
112+
113+ {
114+ await assert . rejects (
115+ ( ) =>
116+ runWorkflowSandbox ( {
117+ parsed : parseWorkflowScript ( `
118+ export const meta = { name: 'constructor-escape', description: 'd' }
119+ return Object.constructor('return process.version')()
120+ ` ) ,
121+ api : api ( { name : "constructor-escape" , description : "d" } ) ,
122+ } ) ,
123+ / p r o c e s s i s n o t d e f i n e d / ,
124+ ) ;
125+ }
126+
127+ {
128+ await assert . rejects (
129+ ( ) =>
130+ runWorkflowSandbox ( {
131+ parsed : parseWorkflowScript ( `
132+ export const meta = { name: 'api-constructor-escape', description: 'd' }
133+ return agent.constructor('return process.version')()
134+ ` ) ,
135+ api : api ( { name : "api-constructor-escape" , description : "d" } ) ,
136+ } ) ,
137+ / p r o c e s s i s n o t d e f i n e d / ,
138+ ) ;
139+ }
140+
87141console . log ( "workflow-sandbox.test.ts: ok" ) ;
0 commit comments