gyscos / gyscos/cursive

[BUG] Printer::on_window panics when printer exceeds backend size instead of degrading gracefully

Open
#885 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
4.8k
Forks
270
Avg merge
5d 19h
Merged PRs (30d)
2

Description

## Summary

`Printer::on_window` turns an anticipated layout failure into a full application panic via `.expect("printer size exceeds backend size")`. When the printer's output window no longer fits the backend buffer — e.g. terminal resized smaller between layout and draw — the app crashes instead of skipping/clipping the draw.

## Location

- File: `cursive-core/src/printer.rs`
- Method: `Printer::on_window()`
- Helper: `cursive-core/src/buffer.rs`, `PrintBuffer::window(viewport: Rect) -> Option` returns `None` when `!viewport.bottom_right().fits_in(self.size)`

Relevant code path (static analysis of current `main`):

```rust
// printer.rs
let mut window = buffer
.window(self.output_window())
.expect("printer size exceeds backend size");
```

```rust
// buffer.rs
pub fn window(&mut self, viewport: Rect) -> Option> {
if !viewport.bottom_right().fits_in(self.size) {
return None;
}
Some(Window { ... })
}
```

The `None` case is explicitly anticipated (hence the message), but handled by panicking.

## Problem

TUI backends resize asynchronously. The draw cycle is layout-then-draw: views are laid out for size N, then the terminal shrinks to M Option` alongside `on_window` so callers can choose. No protocol or layout changes needed; the `window()` `None` signal already exists.

## Evidence

- Source via API: `printer.rs::on_window` expect site plus `buffer.rs::window` `None`-on-overflow contract.
- Duplicate check: issue search for `printer exceeds backend panic` returns `total_count: 0`; open issues contain resize/scroll and menubar-panic topics but no `on_window`-size report (the Hindi-string crash #821 is a distinct `CellWidth` width path) — no apparent duplicate.

**Describe the bug**

Anticipated printer/backend size mismatch panics via `.expect()` in `Printer::on_window` instead of degrading, as detailed above.

**To Reproduce**

Static draw-race path above; minimal live repro would be a view using `on_window` plus a shrink between layout and draw (not executed here).

**Expected behavior**

Skip/clip the out-of-bounds windowed draw for that frame; next layout corrects sizes.

**Screenshots**

N/A

**Environment**

* Operating system used: N/A (code-path finding, backend-independent)
* Backend used: any (race between layout size and backend buffer size)
* Current locale: N/A
* Cursive version: current `main` (verified via API, `cursive-core/src/printer.rs` + `buffer.rs`)

**Additional context**

Non-security correctness/reliability finding; no credentials or runtime artifacts involved.

## Classification

- FACT: `on_window` expects on the exact `None` case `window()` is designed to return (verified in source via API).
- INFERENCE: a stale-size frame (e.g. shrink race) therefore aborts instead of skipping.
- HYPOTHESIS: clipping/skipping on `None` preserves one frame's output with no change to steady-state drawing.

Contributor guide

Open the contributing guide

Research direction

Start in cursive-core/src/printer.rs at Printer::on_window(), then read cursive-core/src/buffer.rs and PrintBuffer::window() to understand the existing None-on-overflow contract. Reproduce or cover the stale-size path if possible, and verify that an oversized window no longer panics while normal windowed drawing remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.