fix(irc): linear OSC stripping, bounded joins and CAP state, no cleartext passwords
- ircformat: an unterminated OSC made the stripper advance two bytes and
rescan the rest, so one hostile 1 MiB line of ESC ] froze the UI thread
for minutes. It now stops at the first OSC with no terminator (none can
follow), which is linear.
- Server lines are capped at 64 KiB (512 bytes + 8 KiB of tags is the
real ceiling) instead of 1 MiB.
- Spoofed self-JOINs can't grow channel state past 500 rooms (they were
also persisted and auto-joined next time); CAP LS is ignored after
registration and its gathered list is capped.
- PASS, SASL PLAIN and NickServ IDENTIFY are only sent over TLS, an SSH
tunnel or a loopback server; otherwise the Server tab says why.
- TcpConn: a local close no longer races the reader into reporting a
spurious read error (regression from 00f110f, which shut the socket
down before taking the stream).
This commit is contained in:
@@ -224,10 +224,10 @@ fn strip_terminal_escapes(value: &str) -> String {
|
||||
s.push_str(&rest[..pos]);
|
||||
rest = &body[end..];
|
||||
}
|
||||
None => {
|
||||
s.push_str(&rest[..pos + 2]);
|
||||
rest = body;
|
||||
}
|
||||
// No terminator anywhere after this OSC, so none after any later OSC either:
|
||||
// keep the rest as is. (Advancing two bytes and searching again was quadratic, and
|
||||
// one hostile 1 MiB line of "\x1b]" froze the UI for minutes.)
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
s.push_str(rest);
|
||||
@@ -425,6 +425,14 @@ mod tests {
|
||||
assert_eq!(plain_text("\x02bold\x02 \x0304red\x03"), "bold red");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unterminated_osc_runs_are_linear() {
|
||||
let start = std::time::Instant::now();
|
||||
let out = plain_text(&"\x1b]".repeat(500_000));
|
||||
assert!(start.elapsed() < std::time::Duration::from_secs(2), "{:?}", start.elapsed());
|
||||
assert!(!out.contains('\x1b'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn untrusted_terminal_sequences_are_removed() {
|
||||
assert_eq!(plain_text("before\x1b[31munsafe\x1b]0;title\x07after"), "beforeunsafeafter");
|
||||
|
||||
Reference in New Issue
Block a user