Skip to content

Commit

Permalink
some \0 aka nul bytes in &str are deleted ...
Browse files Browse the repository at this point in the history
...before sending the &str to ncurses backend,
this is done for cursive's print_at() and print_at_rep() only!
otherwise, nothing would get printed, silently.

Why delete \0 instead of replace with eg. space?
this explains it best:
gyscos#778 (comment)

This also fixes warnings about unused Result.

Closes: gyscos#780
  • Loading branch information
correabuscar committed Jun 5, 2024
1 parent fe73186 commit b3a79dc
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion cursive/src/backends/curses/n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use ncurses;
use log::{debug, warn};
use ncurses::mmask_t;

use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::ffi::CString;
use std::fs::File;
Expand Down Expand Up @@ -403,10 +404,38 @@ impl backend::Backend for Backend {
}

fn print(&self, text: &str) {
ncurses::addstr(text);
// Remove '\0' from &str or else nothing would get printed
// As for why delete instead of replace with eg. space, see:
// https://github.com/gyscos/cursive/pull/778#discussion_r1613859129
let text = &delete_nuls(text);
let len = text.len() as i32;
// Ignore the value to avoid warning: unused `Result` that must be used
let _ = ncurses::addnstr(text, len);
}
}

#[inline(always)]
fn delete_nuls<'a>(text: &'a str) -> Cow<'a, str> {
let text: Cow<'a, str> = if text.contains('\0') {
Cow::Owned(text.replace('\0', ""))
} else {
Cow::Borrowed(text)
};
text
}

#[test]
fn test_print_at_rep_nul_char_in_string() {
let text = "Some\0thing with \0nul\0s\0 in \0it";
let expected = "Something with nuls in it";
assert_eq!(expected, delete_nuls(text));

let backend = Backend::init().unwrap();
// These don't panic, they replace the \0-es with nothing
backend.print_at(Vec2::new(10, 10), "abc\0de\0f");
backend.print_at_rep(Vec2::new(10, 10), 10, "abc\0de\0f");
}

/// Returns the Key enum corresponding to the given ncurses event.
fn get_mouse_button(bare_event: i32) -> MouseButton {
match bare_event {
Expand Down

0 comments on commit b3a79dc

Please sign in to comment.