bxctl: escape frame errors; say the outcome is unknown after a timeout

From the independent review of task 23. serde quotes a bad frame's text after
decoding, so a compromised peer could put escape sequences in it. A timed-out
admin request now says whether brokerd acted is unknown, since it may have.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 21:48:24 -07:00
co-authored by Claude Opus 5.5
parent e08deb39a6
commit bb4d7c0919
4 changed files with 45 additions and 4 deletions
+5 -1
View File
@@ -31,7 +31,11 @@ fn a_silent_brokerd_is_an_error_after_the_timeout() {
Duration::from_millis(200),
);
let took = started.elapsed();
assert!(got.is_err(), "{got:?}");
let text = got.expect_err("a silent brokerd is an error").to_string();
assert!(
text.contains("whether it acted is unknown"),
"brokerd may have approved and run the call before going quiet: {text}"
);
assert!(took < Duration::from_millis(1_500), "waited {took:?}");
held.join().unwrap();
let _ = std::fs::remove_dir_all(&dir);
+18
View File
@@ -55,3 +55,21 @@ fn an_error_detail_is_escaped_in_chat_and_admin_errors() {
assert!(text.contains("\\u202e"), "{text}");
}
}
/// A frame that does not decode is reported with serde's message, which quotes the offending
/// text after JSON decoding: from a compromised peer that can be raw escape sequences.
#[test]
fn a_frame_error_is_escaped() {
let bad = r#"{"v":1,"id":1,"final":true,"msg":{"kind":"\u001b[2J\u202e"}}"#;
let error = serde_json::from_str::<proto::Envelope>(bad).unwrap_err();
for text in [
ChatError::Frame(proto::FrameError::Json(
serde_json::from_str::<proto::Envelope>(bad).unwrap_err(),
))
.to_string(),
AdminError::Frame(proto::FrameError::Json(error)).to_string(),
] {
clean(&text);
assert!(text.contains("\\u001b"), "{text}");
}
}