Skip to content

Commit 4ef913e

Browse files
Validate string timeout command budgets
Validate string timeout command budgets
1 parent ba6bd28 commit 4ef913e

2 files changed

Lines changed: 108 additions & 2 deletions

File tree

app/Http/Controllers/Api/WorkerController.php

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,9 @@ public function completeWorkflowTask(Request $request, string $taskId): JsonResp
488488
'commands.*.timeout_seconds' => ['nullable', 'integer', 'min:0'],
489489
]);
490490

491-
$this->validateWorkflowTaskCommandScopes($validated['commands']);
491+
$commands = $this->normalizeWorkflowTaskCommandIntegerFields($validated['commands']);
492+
493+
$this->validateWorkflowTaskCommandScopes($commands);
492494

493495
if ($response = $this->guardWorkflowTaskOwnership(
494496
$request,
@@ -500,7 +502,7 @@ public function completeWorkflowTask(Request $request, string $taskId): JsonResp
500502
return $response;
501503
}
502504

503-
$commands = WorkflowCommandNormalizer::normalize($validated['commands']);
505+
$commands = WorkflowCommandNormalizer::normalize($commands);
504506

505507
/** @var WorkflowTaskBridge $bridge */
506508
$bridge = app(WorkflowTaskBridge::class);
@@ -598,6 +600,70 @@ private function hasCommandValue(array $command, string $field): bool
598600
return array_key_exists($field, $command) && $command[$field] !== null;
599601
}
600602

603+
/**
604+
* @param list<array<string, mixed>> $commands
605+
* @return list<array<string, mixed>>
606+
*/
607+
private function normalizeWorkflowTaskCommandIntegerFields(array $commands): array
608+
{
609+
$integerFields = [
610+
'start_to_close_timeout',
611+
'schedule_to_start_timeout',
612+
'schedule_to_close_timeout',
613+
'heartbeat_timeout',
614+
'execution_timeout_seconds',
615+
'run_timeout_seconds',
616+
'delay_seconds',
617+
'version',
618+
'min_supported',
619+
'max_supported',
620+
'timeout_seconds',
621+
];
622+
623+
foreach ($commands as $index => $command) {
624+
foreach ($integerFields as $field) {
625+
if (array_key_exists($field, $command)) {
626+
$commands[$index][$field] = $this->normalizeValidatedInteger($command[$field]);
627+
}
628+
}
629+
630+
$retryPolicy = $command['retry_policy'] ?? null;
631+
if (! is_array($retryPolicy)) {
632+
continue;
633+
}
634+
635+
if (array_key_exists('max_attempts', $retryPolicy)) {
636+
$retryPolicy['max_attempts'] = $this->normalizeValidatedInteger($retryPolicy['max_attempts']);
637+
}
638+
639+
$backoffSeconds = $retryPolicy['backoff_seconds'] ?? null;
640+
if (is_array($backoffSeconds)) {
641+
foreach ($backoffSeconds as $backoffIndex => $backoffSecond) {
642+
$backoffSeconds[$backoffIndex] = $this->normalizeValidatedInteger($backoffSecond);
643+
}
644+
645+
$retryPolicy['backoff_seconds'] = $backoffSeconds;
646+
}
647+
648+
$commands[$index]['retry_policy'] = $retryPolicy;
649+
}
650+
651+
return $commands;
652+
}
653+
654+
private function normalizeValidatedInteger(mixed $value): mixed
655+
{
656+
if (is_int($value)) {
657+
return $value;
658+
}
659+
660+
if (is_string($value) && preg_match('/^-?\d+$/', $value) === 1) {
661+
return (int) $value;
662+
}
663+
664+
return $value;
665+
}
666+
601667
/**
602668
* @param array<string, mixed> $command
603669
* @param array<string, list<string>> $errors

tests/Feature/WorkerProtocolContractTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ public static function invalidWorkflowTaskCommandScopeProvider(): array
184184
'errorField' => 'commands.0.heartbeat_timeout',
185185
'expectedMessage' => 'heartbeat_timeout cannot exceed start_to_close_timeout.',
186186
],
187+
'string heartbeat exceeds string start to close' => [
188+
'command' => [
189+
'type' => 'schedule_activity',
190+
'activity_type' => 'tests.external-activity',
191+
'start_to_close_timeout' => '10',
192+
'heartbeat_timeout' => '30',
193+
],
194+
'errorField' => 'commands.0.heartbeat_timeout',
195+
'expectedMessage' => 'heartbeat_timeout cannot exceed start_to_close_timeout.',
196+
],
187197
'schedule to start exceeds schedule to close' => [
188198
'command' => [
189199
'type' => 'schedule_activity',
@@ -194,6 +204,26 @@ public static function invalidWorkflowTaskCommandScopeProvider(): array
194204
'errorField' => 'commands.0.schedule_to_start_timeout',
195205
'expectedMessage' => 'schedule_to_start_timeout cannot exceed schedule_to_close_timeout.',
196206
],
207+
'string start to close exceeds string schedule to close' => [
208+
'command' => [
209+
'type' => 'schedule_activity',
210+
'activity_type' => 'tests.external-activity',
211+
'start_to_close_timeout' => '60',
212+
'schedule_to_close_timeout' => '30',
213+
],
214+
'errorField' => 'commands.0.start_to_close_timeout',
215+
'expectedMessage' => 'start_to_close_timeout cannot exceed schedule_to_close_timeout.',
216+
],
217+
'string schedule to start exceeds string schedule to close' => [
218+
'command' => [
219+
'type' => 'schedule_activity',
220+
'activity_type' => 'tests.external-activity',
221+
'schedule_to_start_timeout' => '60',
222+
'schedule_to_close_timeout' => '30',
223+
],
224+
'errorField' => 'commands.0.schedule_to_start_timeout',
225+
'expectedMessage' => 'schedule_to_start_timeout cannot exceed schedule_to_close_timeout.',
226+
],
197227
'child run exceeds execution' => [
198228
'command' => [
199229
'type' => 'start_child_workflow',
@@ -204,6 +234,16 @@ public static function invalidWorkflowTaskCommandScopeProvider(): array
204234
'errorField' => 'commands.0.run_timeout_seconds',
205235
'expectedMessage' => 'run_timeout_seconds cannot exceed execution_timeout_seconds.',
206236
],
237+
'string child run exceeds string execution' => [
238+
'command' => [
239+
'type' => 'start_child_workflow',
240+
'workflow_type' => 'tests.external-child-workflow',
241+
'execution_timeout_seconds' => '60',
242+
'run_timeout_seconds' => '120',
243+
],
244+
'errorField' => 'commands.0.run_timeout_seconds',
245+
'expectedMessage' => 'run_timeout_seconds cannot exceed execution_timeout_seconds.',
246+
],
207247
];
208248
}
209249

0 commit comments

Comments
 (0)