From 28841a8722993c6330cb584c634bdc28c07e5b96 Mon Sep 17 00:00:00 2001 From: O6lvl4 <96694331+O6lvl4@users.noreply.github.com> Date: Sun, 4 Oct 2026 08:03:31 +0900 Subject: [PATCH] Escape HTTP error responses as valid JSON --- native/http_client.rs | 8 ++++---- src/wasm_rt_test.almd | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/native/http_client.rs b/native/http_client.rs index 7b0cfd6..2d3c74d 100644 --- a/native/http_client.rs +++ b/native/http_client.rs @@ -10,16 +10,16 @@ use crate::json_text::escape_json_text; pub fn wt_http_request(method: impl AsRef, url: impl AsRef, headers_json: impl AsRef, body: impl AsRef) -> String { let client = match checked_client() { Ok(client) => client, - Err(reason) => return format!("{{\"error\":\"client error: {}\"}}", reason), + Err(reason) => return format!("{{\"error\":\"client error: {}\"}}", escape_json_text(&reason.to_string())), }; let Some(mut request) = request_for(&client, method.as_ref(), url.as_ref()) else { - return format!("{{\"error\":\"unsupported method: {}\"}}", method.as_ref()); + return format!("{{\"error\":\"unsupported method: {}\"}}", escape_json_text(method.as_ref())); }; request = with_headers(request, headers_json.as_ref()); if !body.as_ref().is_empty() { request = request.body(body.as_ref().to_string()); } match request.send() { Ok(response) => encoded_response(response), - Err(error) => format!("{{\"error\":\"request failed: {}\"}}", error), + Err(error) => format!("{{\"error\":\"request failed: {}\"}}", escape_json_text(&error.to_string())), } } @@ -62,6 +62,6 @@ fn encoded_response(response: reqwest::blocking::Response) -> String { let status = response.status().as_u16(); match response.text() { Ok(text) => format!("{{\"status\":{},\"body\":\"{}\"}}", status, escape_json_text(&text)), - Err(error) => format!("{{\"error\":\"read error: {}\"}}", error), + Err(error) => format!("{{\"error\":\"read error: {}\"}}", escape_json_text(&error.to_string())), } } diff --git a/src/wasm_rt_test.almd b/src/wasm_rt_test.almd index c30a6b6..1fed53f 100644 --- a/src/wasm_rt_test.almd +++ b/src/wasm_rt_test.almd @@ -16,6 +16,15 @@ test "wt_http_request: invalid URL" { } } +test "wt_http_request: unsupported method is valid JSON" { + // Rejected before a request is sent, even when the method contains JSON + // delimiters, control characters or Unicode. + let method = "BAD" + string.from_bytes([34, 92, 10, 13, 9, 0, 1, 8, 12, 31]) + "日" + let resp = wasm_rt.wt_http_request(method, "http://127.0.0.1", "{}", "")! + let parsed = json.parse(resp)! + assert_eq(json.get_string(parsed, "error") ?? "", "unsupported method: " + method) +} + // --- wt_exec_command --- test "wt_exec_command: echo" {