commit 146ecee3cc2ed21587f066cad168dd6c46d053ae
parent d25662acf18f08845ca64cc95b9cf66238cff710
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 13:59:27 +0000
runtime: recover from malformed framed requests
Diffstat:
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/src/hyf_stdio/server.mojo b/src/hyf_stdio/server.mojo
@@ -309,14 +309,25 @@ def run_stdio_server() raises:
)
+def handle_frame(frame: String, runtime_context: RuntimeStartupContext) raises -> String:
+ if frame_too_large(frame):
+ return encode_error(
+ WireErrorResponse(
+ version=hyf_protocol_version(),
+ request_id="",
+ trace_id=None,
+ error=invalid_request_error("request frame exceeds the size limit"),
+ )
+ )
+ return handle_request_line_with_runtime_context(frame, runtime_context)
+
+
def run_stdio_session(
frames: List[String], runtime_context: RuntimeStartupContext
) raises -> List[String]:
var responses = List[String]()
for frame in frames:
- responses.append(
- handle_request_line_with_runtime_context(frame, runtime_context)
- )
+ responses.append(handle_frame(frame, runtime_context))
return responses^
@@ -331,7 +342,7 @@ def run_stdio_server_with_runtime_context(
var line = input_file.readline()
if line == "":
break
- print(handle_request_line_with_runtime_context(line, runtime_context))
+ print(handle_frame(line, runtime_context))
comptime MAX_FRAME_BYTES = 1048576
diff --git a/tests/test_persistent_stdio.mojo b/tests/test_persistent_stdio.mojo
@@ -66,3 +66,17 @@ def test_session_preserves_order_and_recovers_after_malformed() raises:
assert_true(responses[1].find('invalid_request') >= 0)
assert_true(responses[2].find('"ok":true') >= 0)
assert_true(responses[2].find('business_capabilities') >= 0)
+
+
+def test_session_rejects_oversized_frame() raises:
+ with TemporaryDirectory() as temp_dir:
+ var context = _context(temp_dir)
+ var huge = "{\"version\":1,\"request_id\":\"big\","
+ for _ in range(200000):
+ huge += "x"
+ var frames = List[String]()
+ frames.append(huge)
+ frames.append(load_scenario_request_json("scenarios/status_ok.json"))
+ var responses = run_stdio_session(frames, context)
+ assert_true(responses[0].find("size limit") >= 0)
+ assert_true(responses[1].find('"ok":true') >= 0)