bxctl: escape error details, time out on admin.sock, AdminError::Io
M3a review findings 9, 10, 12, 13. A retrying error and every error detail can carry the inference server's body, so they are escaped like model text. Admin requests wait at most 30 s, so a stuck brokerd cannot hang bxctl or a chat turn. A failed write is AdminError::Io and stops handle_pending instead of being answered with another write. The usage line says what audit verify checks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
//! Text from `brokerd` or the inference server is escaped like model text before it reaches the
|
||||
//! terminal: a `retrying` error and every error detail (M3a review finding 10).
|
||||
|
||||
use bxctl::admin::AdminError;
|
||||
use bxctl::chat::{ChatError, Printer};
|
||||
use proto::{ErrorCode, TurnEvent, WireError};
|
||||
|
||||
const ESC: char = '\u{1b}';
|
||||
|
||||
fn hostile() -> String {
|
||||
format!("the server responded with 503: {ESC}[2J{ESC}]0;owned\u{7}\u{202e}")
|
||||
}
|
||||
|
||||
fn clean(text: &str) {
|
||||
for c in text.chars() {
|
||||
let cp = u32::from(c);
|
||||
assert!(
|
||||
cp >= 0x20 && !(0x7f..=0x9f).contains(&cp) && !(0x2028..=0x202e).contains(&cp)
|
||||
|| c == '\n',
|
||||
"raw {cp:#x} in {text:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_retrying_error_is_escaped() {
|
||||
let mut out = Vec::new();
|
||||
let mut printer = Printer::new(true, false);
|
||||
printer
|
||||
.event(
|
||||
&mut out,
|
||||
&TurnEvent::Retrying {
|
||||
attempt: 1,
|
||||
after_ms: 2000,
|
||||
error: hostile(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let text = String::from_utf8(out).unwrap();
|
||||
clean(&text);
|
||||
assert!(text.contains("\\u001b[2J"), "{text}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_error_detail_is_escaped_in_chat_and_admin_errors() {
|
||||
let wire = WireError {
|
||||
code: ErrorCode::Inference,
|
||||
detail: hostile(),
|
||||
};
|
||||
for text in [
|
||||
ChatError::Refused(wire.clone()).to_string(),
|
||||
AdminError::Refused(wire).to_string(),
|
||||
] {
|
||||
clean(&text);
|
||||
assert!(text.contains("\\u202e"), "{text}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user