diff --git a/CHANGELOG.md b/CHANGELOG.md index 468335a..5baeee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.1] - unreleased + +## Fix + +- Fix a panic when working with extreme paddings, where `(padding.left + padding.right) > u16::MAX`. +- Fix a panic when working with extremely long content, where `(content_width + padding) > u16::MAX`. + ## [7.0.0] - 2023-06-06 ### Breaking diff --git a/src/column.rs b/src/column.rs index ac7f734..742fac9 100644 --- a/src/column.rs +++ b/src/column.rs @@ -62,9 +62,9 @@ impl Column { self } - /// Internal convenience helper that returns the total width of the combined padding. - pub(crate) fn padding_width(&self) -> u16 { - self.padding.0 + self.padding.1 + /// Convenience helper that returns the total width of the combined padding. + pub fn padding_width(&self) -> u16 { + self.padding.0.saturating_add(self.padding.1) } /// Set the delimiter used to split text for this column's cells. diff --git a/src/utils/arrangement/helper.rs b/src/utils/arrangement/helper.rs index 6994f0b..43866b8 100644 --- a/src/utils/arrangement/helper.rs +++ b/src/utils/arrangement/helper.rs @@ -11,13 +11,14 @@ use crate::{Cell, Column, Table}; /// For this reason, we take the targeted width, subtract the column's padding and make sure that /// the content width is always a minimum of 1 pub fn absolute_width_with_padding(column: &Column, width: u16) -> u16 { - let (left, right) = column.padding; - let mut content_width = i32::from(width) - i32::from(left) - i32::from(right); - if content_width <= 0 { + let mut content_width = width + .saturating_sub(column.padding.0) + .saturating_sub(column.padding.1); + if content_width == 0 { content_width = 1; } - content_width.try_into().unwrap_or(u16::MAX) + content_width } /// Return the amount of visible columns diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 61fb250..ff6ea62 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -41,7 +41,9 @@ impl ColumnDisplayInfo { } pub fn width(&self) -> u16 { - self.content_width + self.padding.0 + self.padding.1 + self.content_width + .saturating_add(self.padding.0) + .saturating_add(self.padding.1) } } diff --git a/tests/all/edge_cases.rs b/tests/all/edge_cases.rs new file mode 100644 index 0000000..4771843 --- /dev/null +++ b/tests/all/edge_cases.rs @@ -0,0 +1,23 @@ +use comfy_table::*; + +/// A gigantic table can generated, even if it's longer than the longest supported width. +#[test] +fn giant_table() { + let mut table = Table::new(); + table.set_header(["a".repeat(1_000_000)]); + table.add_row(["a".repeat(1_000_000)]); + + table.to_string(); +} + +/// No panic, even if there's a ridiculous amount of padding. +#[test] +fn max_padding() { + let mut table = Table::new(); + table.add_row(["test"]); + let column = table.column_mut(0).unwrap(); + + column.set_padding((u16::MAX, u16::MAX)); + + table.to_string(); +} diff --git a/tests/all/mod.rs b/tests/all/mod.rs index 53055d8..29f4d2d 100644 --- a/tests/all/mod.rs +++ b/tests/all/mod.rs @@ -8,6 +8,7 @@ mod combined_test; mod constraints_test; mod content_arrangement_test; mod custom_delimiter_test; +mod edge_cases; mod hidden_test; #[cfg(feature = "custom_styling")] mod inner_style_test;