Skip to content

Commit ad87343

Browse files
committed
fix(runtime): bound worker request payloads
1 parent 4dc270e commit ad87343

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

maf_starter/loop_worker_cli.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
run_bounded_specialists,
1515
)
1616

17+
MAX_REQUEST_BYTES = 1_000_000
18+
1719

1820
@dataclass(frozen=True)
1921
class WorkerEnvelope:
@@ -68,7 +70,15 @@ def main() -> int:
6870
parser.add_argument("--request", help="JSON worker request; stdin is used when omitted")
6971
args = parser.parse_args()
7072
try:
71-
payload = json.loads(args.request if args.request is not None else sys.stdin.read())
73+
if args.request is not None:
74+
request_text = args.request
75+
request_size = len(request_text.encode("utf-8"))
76+
else:
77+
request_text = sys.stdin.read(MAX_REQUEST_BYTES + 1)
78+
request_size = len(request_text.encode("utf-8"))
79+
if request_size > MAX_REQUEST_BYTES:
80+
raise ValueError(f"Worker request exceeds {MAX_REQUEST_BYTES} bytes")
81+
payload = json.loads(request_text)
7282
result = asyncio.run(execute_request(payload))
7383
except (ValueError, json.JSONDecodeError) as error:
7484
print(json.dumps({"error": str(error)}), file=sys.stderr)

tests/test_loop_worker_cli.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import asyncio
2+
import io
3+
import json
4+
import sys
25
import unittest
6+
from contextlib import redirect_stderr
7+
from unittest.mock import patch
38

4-
from maf_starter.loop_worker_cli import execute_request
9+
from maf_starter.loop_worker_cli import MAX_REQUEST_BYTES, execute_request, main
510

611

712
class LoopWorkerCliTests(unittest.TestCase):
@@ -22,3 +27,17 @@ def test_cli_request_executes_real_bounded_specialist_runtime(self) -> None:
2227
self.assertEqual(3, result.peakConcurrency)
2328
self.assertEqual(("research", "architecture", "security", "test"), result.roles)
2429
self.assertEqual(4, len(result.evidenceUris))
30+
31+
def test_cli_rejects_oversized_stdin_before_json_parsing(self) -> None:
32+
oversized = json.dumps({"padding": "x" * MAX_REQUEST_BYTES})
33+
stderr = io.StringIO()
34+
35+
with (
36+
patch.object(sys, "argv", ["loop_worker_cli"]),
37+
patch.object(sys, "stdin", io.StringIO(oversized)),
38+
redirect_stderr(stderr),
39+
):
40+
exit_code = main()
41+
42+
self.assertEqual(2, exit_code)
43+
self.assertIn("exceeds", stderr.getvalue())

0 commit comments

Comments
 (0)