gyscos / gyscos/cursive

[BUG] Incorrect line width calculation with strings containing control characters

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

Description

**Describe the bug**
When a string contains the unicode character U+0003 '^C', a control character used by IRC to [denote color](https://modern.ircdocs.horse/formatting.html#color), cursive's `print()` function can overflow and print outside the boundaries of a view.

I believe this occurs because the unicode-width crate [treats control characters as zero-width](https://unicode-rs.github.io/unicode-width/unicode_width/trait.UnicodeWidthStr.html#tymethod.width), but ncurses renders U+0003 as two characters: `^C`. So ncurses will render a string that is longer than what unicode-width reports. Similar behavior occurs with U+0002 '^B', and likely other control chars.

**To Reproduce**
Cursive's lorem example can be modified to reproduce the bug by adding code to the top of `lorem.rs` as follows:
```
use cursive::{
align::HAlign,
event::{EventResult, Key},
traits::With,
view::{scroll::Scroller, Scrollable},
views::{Dialog, OnEventView, Panel, TextView},
};

fn main() {
// Read some long text from a file.
// modify content to be mutable
let mut content = include_str!("assets/lorem.txt").to_string();

// add several ^C chars to the end of the content
for _ in 1..100 {
content.push_str("\u{0003}");
}
let mut siv = cursive::default();

// We can quit by pressing q
siv.add_global_callback('q', |s| s.quit());

// The text is too long to fit on a line, so the view will wrap lines,

...
```

Running the example and scrolling to the bottom results in an overflow:
![lorem_bug](https://user-images.githubusercontent.com/32023353/152279031-60ad52ce-ff99-4c66-aff2-ea21a0547043.png)

**Expected behavior**
Either control characters should not be rendered, conforming to unicode-width's expectations, or our truncation logic should be modified to accurately reflect ncurses' output.

**Environment**
* Operating system: Linux (Manjaro/alacritty)
* Backend used: ncurses
* Current locale: en_US.utf8
* Cursive version: 0.17

**Additional context**
The bug was discovered while working on an IRC client, before handling for IRC special characters was added. I made the lorem repro to avoid getting bogged down in the wonky custom view I use for rendering chats. If necessary, I can provide that code as well.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.