editor: Do not panic on tab_size > 16, cap it at 128 (#38994)
Fixes ZED-1PT Fixes ZED-1PW Fixes ZED-1G2 Release Notes: - Fixed Zed panicking when the `tab_size` is set higher than 16
This commit is contained in:
@@ -26,8 +26,8 @@ use sum_tree::{Bias, ContextLessSummary, Dimensions, SumTree, TreeMap};
|
||||
use text::{BufferId, Edit};
|
||||
use ui::ElementId;
|
||||
|
||||
const NEWLINES: &[u8] = &[b'\n'; u128::BITS as usize];
|
||||
const BULLETS: &str = "********************************************************************************************************************************";
|
||||
const NEWLINES: &[u8; u128::BITS as usize] = &[b'\n'; _];
|
||||
const BULLETS: &[u8; u128::BITS as usize] = &[b'*'; _];
|
||||
|
||||
/// Tracks custom blocks such as diagnostics that should be displayed within buffer.
|
||||
///
|
||||
@@ -1774,7 +1774,7 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
// need to have the same number of bytes in the input as output.
|
||||
let chars_count = prefix.chars().count();
|
||||
let bullet_len = chars_count;
|
||||
prefix = &BULLETS[..bullet_len];
|
||||
prefix = unsafe { std::str::from_utf8_unchecked(&BULLETS[..bullet_len]) };
|
||||
chars = 1u128.unbounded_shl(bullet_len as u32) - 1;
|
||||
tabs = 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ use sum_tree::Bias;
|
||||
|
||||
const MAX_EXPANSION_COLUMN: u32 = 256;
|
||||
|
||||
// Handles a tab width <= 128
|
||||
const SPACES: &[u8; u128::BITS as usize] = &[b' '; _];
|
||||
const MAX_TABS: NonZeroU32 = NonZeroU32::new(SPACES.len() as u32).unwrap();
|
||||
|
||||
/// Keeps track of hard tabs in a text buffer.
|
||||
///
|
||||
/// See the [`display_map` module documentation](crate::display_map) for more information.
|
||||
@@ -19,7 +23,7 @@ impl TabMap {
|
||||
pub fn new(fold_snapshot: FoldSnapshot, tab_size: NonZeroU32) -> (Self, TabSnapshot) {
|
||||
let snapshot = TabSnapshot {
|
||||
fold_snapshot,
|
||||
tab_size,
|
||||
tab_size: tab_size.min(MAX_TABS),
|
||||
max_expansion_column: MAX_EXPANSION_COLUMN,
|
||||
version: 0,
|
||||
};
|
||||
@@ -41,7 +45,7 @@ impl TabMap {
|
||||
let old_snapshot = &mut self.0;
|
||||
let mut new_snapshot = TabSnapshot {
|
||||
fold_snapshot,
|
||||
tab_size,
|
||||
tab_size: tab_size.min(MAX_TABS),
|
||||
max_expansion_column: old_snapshot.max_expansion_column,
|
||||
version: old_snapshot.version,
|
||||
};
|
||||
@@ -266,7 +270,7 @@ impl TabSnapshot {
|
||||
max_output_position: range.end.0,
|
||||
tab_size: self.tab_size,
|
||||
chunk: Chunk {
|
||||
text: &SPACES[0..(to_next_stop as usize)],
|
||||
text: unsafe { std::str::from_utf8_unchecked(&SPACES[..to_next_stop as usize]) },
|
||||
is_tab: true,
|
||||
..Default::default()
|
||||
},
|
||||
@@ -317,13 +321,11 @@ impl TabSnapshot {
|
||||
let (collapsed, expanded_char_column, to_next_stop) =
|
||||
self.collapse_tabs(tab_cursor, expanded, bias);
|
||||
|
||||
let result = (
|
||||
(
|
||||
FoldPoint::new(output.row(), collapsed),
|
||||
expanded_char_column,
|
||||
to_next_stop,
|
||||
);
|
||||
|
||||
result
|
||||
)
|
||||
}
|
||||
|
||||
pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint {
|
||||
@@ -510,9 +512,6 @@ impl<'a> std::ops::AddAssign<&'a Self> for TextSummary {
|
||||
}
|
||||
}
|
||||
|
||||
// Handles a tab width <= 16
|
||||
const SPACES: &str = " ";
|
||||
|
||||
pub struct TabChunks<'a> {
|
||||
snapshot: &'a TabSnapshot,
|
||||
fold_chunks: FoldChunks<'a>,
|
||||
@@ -549,7 +548,7 @@ impl TabChunks<'_> {
|
||||
self.output_position = range.start.0;
|
||||
self.max_output_position = range.end.0;
|
||||
self.chunk = Chunk {
|
||||
text: &SPACES[0..(to_next_stop as usize)],
|
||||
text: unsafe { std::str::from_utf8_unchecked(&SPACES[..to_next_stop as usize]) },
|
||||
is_tab: true,
|
||||
chars: 1u128.unbounded_shl(to_next_stop) - 1,
|
||||
..Default::default()
|
||||
@@ -621,7 +620,7 @@ impl<'a> Iterator for TabChunks<'a> {
|
||||
self.input_column += 1;
|
||||
self.output_position = next_output_position;
|
||||
return Some(Chunk {
|
||||
text: &SPACES[..len as usize],
|
||||
text: unsafe { std::str::from_utf8_unchecked(&SPACES[..len as usize]) },
|
||||
is_tab: true,
|
||||
chars: 1u128.unbounded_shl(len) - 1,
|
||||
tabs: 0,
|
||||
|
||||
@@ -749,6 +749,7 @@ pub struct LanguageConfig {
|
||||
pub hard_tabs: Option<bool>,
|
||||
/// How many columns a tab should occupy.
|
||||
#[serde(default)]
|
||||
#[schemars(range(min = 1, max = 128))]
|
||||
pub tab_size: Option<NonZeroU32>,
|
||||
/// How to soft-wrap long lines of text.
|
||||
#[serde(default)]
|
||||
@@ -845,6 +846,7 @@ pub struct BlockCommentConfig {
|
||||
/// A character to add as a prefix when a new line is added to a block comment.
|
||||
pub prefix: Arc<str>,
|
||||
/// A indent to add for prefix and end line upon new line.
|
||||
#[schemars(range(min = 1, max = 128))]
|
||||
pub tab_size: u32,
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ pub struct LanguageSettingsContent {
|
||||
/// How many columns a tab should occupy.
|
||||
///
|
||||
/// Default: 4
|
||||
#[schemars(range(min = 1, max = 128))]
|
||||
pub tab_size: Option<NonZeroU32>,
|
||||
/// Whether to indent lines using tab characters, as opposed to multiple
|
||||
/// spaces.
|
||||
|
||||
Reference in New Issue
Block a user