getty: reject implausible size-probe results (fix odd shell wrapping)

The cursor-report size probe (tty_columns_lines: Save + Goto(999,999) +
\x1B[6n) is unreliable on the fbcond console. console_draw does not clamp Goto
beyond the real screen bounds, so the \x1B[6n reply can report the *current*
cursor position mid boot-text (observed 15x56) instead of the actual
dimensions. A bogus 15-column width makes the login shell wrap every line
oddly.

Keep the probe result only when both dimensions are plausible (cols 40..=1000,
lines 10..=1000); otherwise fall back to the safe 80x30 default, which
mis-wraps on no real framebuffer. A correct full-size reading needs
fbcond/console_draw to answer the probe properly (tracked separately).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-25 17:51:03 +09:00
parent bc290c14b3
commit 1e727ca1bd
+26 -1
View File
@@ -48,6 +48,14 @@ AUTHOR
const DEFAULT_COLS: u16 = 80;
const DEFAULT_LINES: u16 = 30;
// Plausibility bounds for the cursor-report size probe (see `daemon`). The
// probe is unreliable on the fbcond console, so anything outside this range is
// treated as a bad reading and replaced with the safe defaults above.
const MIN_PLAUSIBLE_COLS: u16 = 40;
const MAX_PLAUSIBLE_COLS: u16 = 1000;
const MIN_PLAUSIBLE_LINES: u16 = 10;
const MAX_PLAUSIBLE_LINES: u16 = 1000;
pub fn handle(
event_queue: &mut RawEventQueue,
tty_fd: RawFd,
@@ -225,7 +233,24 @@ fn tty_columns_lines(tty: &mut File) -> Result<(u16, u16), Box<dyn Error>> {
}
fn daemon(tty: &mut File, clear: bool, contain: bool, stderr: &mut Stderr) {
let (columns, lines) = tty_columns_lines(tty).unwrap_or((DEFAULT_COLS, DEFAULT_LINES));
// The cursor-report size probe (tty_columns_lines: Save + Goto(999,999) +
// \x1B[6n) is unreliable on the fbcond console. console_draw does not clamp
// Goto beyond the real screen bounds, so the \x1B[6n reply can report the
// *current* cursor position mid boot-text (observed: 15x56) instead of the
// actual dimensions. A bogus tiny width makes the login shell wrap every
// line oddly. Keep the probe result only when it is plausible; otherwise
// fall back to the safe 80x30 default, which mis-wraps on no real
// framebuffer. (A correct size needs fbcond/console_draw to answer the
// probe properly — tracked separately.)
let (columns, lines) = match tty_columns_lines(tty) {
Ok((c, l))
if (MIN_PLAUSIBLE_COLS..=MAX_PLAUSIBLE_COLS).contains(&c)
&& (MIN_PLAUSIBLE_LINES..=MAX_PLAUSIBLE_LINES).contains(&l) =>
{
(c, l)
}
_ => (DEFAULT_COLS, DEFAULT_LINES),
};
let tty_fd = tty.as_raw_fd();
let (master_fd, pty) = getpty(columns, lines);