mirror of
https://github.com/wez/wezterm.git
synced 2024-11-10 15:04:32 +03:00
Defend against crazy big images sent via iterm image protocol
This also handles a Nan case and allows us to survive term-crash-tests as of fb6fa3192a65e8862c3c743ba102f7e2af45b519 refs: https://github.com/wez/wezterm/issues/1031
This commit is contained in:
parent
7dd77a03da
commit
24d971c87d
@ -1,7 +1,8 @@
|
||||
use crate::{Position, StableRowIndex, TerminalState};
|
||||
use anyhow::Context;
|
||||
use ordered_float::NotNan;
|
||||
use std::sync::Arc;
|
||||
use termwiz::cell::{Cell, CellAttributes};
|
||||
use termwiz::cell::Cell;
|
||||
use termwiz::image::{ImageCell, ImageDataType};
|
||||
use termwiz::surface::change::ImageData;
|
||||
use termwiz::surface::TextureCoordinate;
|
||||
@ -57,7 +58,10 @@ pub enum ImageAttachStyle {
|
||||
}
|
||||
|
||||
impl TerminalState {
|
||||
pub(crate) fn assign_image_to_cells(&mut self, params: ImageAttachParams) -> PlacementInfo {
|
||||
pub(crate) fn assign_image_to_cells(
|
||||
&mut self,
|
||||
params: ImageAttachParams,
|
||||
) -> anyhow::Result<PlacementInfo> {
|
||||
let seqno = self.seqno;
|
||||
let physical_cols = self.screen().physical_cols;
|
||||
let physical_rows = self.screen().physical_rows;
|
||||
@ -81,10 +85,10 @@ impl TerminalState {
|
||||
|
||||
let first_row = self.screen().visible_row_to_stable_row(self.cursor.y);
|
||||
|
||||
let mut ypos =
|
||||
NotNan::new(params.source_origin_y as f32 / params.image_height as f32).unwrap();
|
||||
let start_xpos =
|
||||
NotNan::new(params.source_origin_x as f32 / params.image_width as f32).unwrap();
|
||||
let mut ypos = NotNan::new(params.source_origin_y as f32 / params.image_height as f32)
|
||||
.context("computing ypos")?;
|
||||
let start_xpos = NotNan::new(params.source_origin_x as f32 / params.image_width as f32)
|
||||
.context("computing xpos")?;
|
||||
|
||||
let cursor_x = self.cursor.x;
|
||||
let x_delta = (source_width as f32 / params.image_width as f32) / width_in_cells as f32;
|
||||
@ -126,7 +130,7 @@ impl TerminalState {
|
||||
.screen()
|
||||
.get_cell(cursor_x + x, cursor_y)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Cell::new(' ', CellAttributes::default()));
|
||||
.unwrap_or_else(Cell::blank);
|
||||
let img = Box::new(ImageCell::with_z_index(
|
||||
TextureCoordinate::new(xpos, ypos),
|
||||
TextureCoordinate::new(xpos + x_delta, ypos + y_delta),
|
||||
@ -171,11 +175,11 @@ impl TerminalState {
|
||||
}
|
||||
}
|
||||
|
||||
PlacementInfo {
|
||||
Ok(PlacementInfo {
|
||||
first_row,
|
||||
rows: height_in_cells,
|
||||
cols: width_in_cells,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// cache recent images and avoid assigning a new id for repeated data!
|
||||
|
@ -50,6 +50,19 @@ impl TerminalState {
|
||||
}
|
||||
};
|
||||
|
||||
const MAX_IMAGE_SIZE: u32 = 100_000_000;
|
||||
let size = info.width.saturating_mul(info.height).saturating_mul(4);
|
||||
if size > MAX_IMAGE_SIZE {
|
||||
log::error!(
|
||||
"Ignoring iterm image data {}x{} because {} bytes > max allowed {}",
|
||||
info.width,
|
||||
info.height,
|
||||
size,
|
||||
MAX_IMAGE_SIZE
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out the dimensions.
|
||||
let physical_cols = self.screen().physical_cols;
|
||||
let physical_rows = self.screen().physical_rows;
|
||||
@ -122,7 +135,7 @@ impl TerminalState {
|
||||
};
|
||||
|
||||
let image_data = self.raw_image_to_image_data(data);
|
||||
self.assign_image_to_cells(ImageAttachParams {
|
||||
if let Err(err) = self.assign_image_to_cells(ImageAttachParams {
|
||||
image_width: width as u32,
|
||||
image_height: height as u32,
|
||||
source_width: width as u32,
|
||||
@ -139,6 +152,8 @@ impl TerminalState {
|
||||
image_id: None,
|
||||
placement_id: None,
|
||||
do_not_move_cursor: false,
|
||||
});
|
||||
}) {
|
||||
log::error!("set iterm2 image: {:#}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ impl TerminalState {
|
||||
image_id: Some(image_id),
|
||||
placement_id: placement.placement_id,
|
||||
do_not_move_cursor: placement.do_not_move_cursor,
|
||||
});
|
||||
})?;
|
||||
|
||||
self.kitty_img
|
||||
.placements
|
||||
|
@ -107,7 +107,7 @@ impl TerminalState {
|
||||
let image_data = ImageDataType::new_single_frame(width, height, data);
|
||||
|
||||
let image_data = self.raw_image_to_image_data(image_data);
|
||||
self.assign_image_to_cells(ImageAttachParams {
|
||||
if let Err(err) = self.assign_image_to_cells(ImageAttachParams {
|
||||
image_width: width,
|
||||
image_height: height,
|
||||
source_width: width,
|
||||
@ -124,6 +124,8 @@ impl TerminalState {
|
||||
image_id: None,
|
||||
placement_id: None,
|
||||
do_not_move_cursor: false,
|
||||
});
|
||||
}) {
|
||||
log::error!("set sixel image: {:#}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user