1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +03:00

fix potential panic when pasting multibyte text > 1024 bytes

We were handling the case where the chunk intersected a multibyte
boundary after the first chunk, but not for the first chunk itself.

Refactor the code so that we use the same chunk splitting logic
for both of those cases.

refs: https://github.com/wez/wezterm/issues/668
This commit is contained in:
Wez Furlong 2021-04-09 11:47:42 -07:00
parent 0694e905e8
commit dfb6043971

View File

@ -43,29 +43,33 @@ struct Paste {
offset: usize,
}
fn paste_next_chunk(paste: &Arc<Mutex<Paste>>) {
let mut locked = paste.lock().unwrap();
let mux = Mux::get().unwrap();
let pane = mux.get_pane(locked.pane_id).unwrap();
let remain = locked.text.len() - locked.offset;
let mut chunk = remain.min(PASTE_CHUNK_SIZE);
// Make sure we chunk at a char boundary, otherwise the
// slice operation below will panic
while !locked.text.is_char_boundary(locked.offset + chunk) && chunk < remain {
chunk += 1;
}
let text_slice = &locked.text[locked.offset..locked.offset + chunk];
pane.send_paste(text_slice).unwrap();
if chunk < remain {
// There is more to send
locked.offset += chunk;
schedule_next_paste(paste);
}
}
fn schedule_next_paste(paste: &Arc<Mutex<Paste>>) {
let paste = Arc::clone(paste);
promise::spawn::spawn(async move {
let mut locked = paste.lock().unwrap();
let mux = Mux::get().unwrap();
let pane = mux.get_pane(locked.pane_id).unwrap();
let remain = locked.text.len() - locked.offset;
let mut chunk = remain.min(PASTE_CHUNK_SIZE);
// Make sure we chunk at a char boundary, otherwise the
// slice operation below will panic
while !locked.text.is_char_boundary(locked.offset + chunk) && chunk < remain {
chunk += 1;
}
let text_slice = &locked.text[locked.offset..locked.offset + chunk];
pane.send_paste(text_slice).unwrap();
if chunk < remain {
// There is more to send
locked.offset += chunk;
schedule_next_paste(&paste);
}
paste_next_chunk(&paste);
})
.detach();
}
@ -320,14 +324,12 @@ pub trait Pane: Downcast {
self.send_paste(&text)?;
} else {
// It's pretty heavy, so we trickle it into the pty
self.send_paste(&text[0..PASTE_CHUNK_SIZE])?;
let paste = Arc::new(Mutex::new(Paste {
pane_id: self.pane_id(),
text,
offset: PASTE_CHUNK_SIZE,
offset: 0,
}));
schedule_next_paste(&paste);
paste_next_chunk(&paste);
}
Ok(())
}