From b9a4be3750121100da72e599efea26bf1d633d1f Mon Sep 17 00:00:00 2001 From: Makoto Date: Fri, 25 Jun 2021 13:08:08 -0700 Subject: [PATCH] wrap_optimal_fit() - Checked arithmetic --- src/lib.rs | 5 +++++ src/wrap_algorithms/optimal_fit.rs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 02cc0e40..d18eaacd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1851,6 +1851,11 @@ mod tests { ); } + #[test] + fn fill_large_width() { + fill("!@", 18446743798827450368); + } + #[test] #[cfg(not(feature = "smawk"))] #[cfg(not(feature = "unicode-linebreak"))] diff --git a/src/wrap_algorithms/optimal_fit.rs b/src/wrap_algorithms/optimal_fit.rs index 7e3c99e2..0461e5b1 100644 --- a/src/wrap_algorithms/optimal_fit.rs +++ b/src/wrap_algorithms/optimal_fit.rs @@ -272,7 +272,7 @@ pub fn wrap_optimal_fit<'a, 'b, T: Fragment>( // breaking before fragments[i]. // // First, every extra line cost NLINE_PENALTY. - let mut cost = minima[i].1 + penalties.nline_penalty; + let mut cost = (minima[i].1 as i32).saturating_add(penalties.nline_penalty); // Next, we add a penalty depending on the line length. if line_width > target_width { @@ -283,12 +283,12 @@ pub fn wrap_optimal_fit<'a, 'b, T: Fragment>( // Other lines (except for the last line) get a milder // penalty which depend on the size of the gap. let gap = (target_width - line_width) as i32; - cost += gap * gap; + cost = cost.saturating_add(gap.saturating_mul(gap)); } else if i + 1 == j && line_width < target_width / penalties.short_last_line_fraction { // The last line can have any size gap, but we do add a // penalty if the line is very short (typically because it // contains just a single word). - cost += penalties.short_last_line_penalty; + cost = cost.saturating_add(penalties.short_last_line_penalty); } // Finally, we discourage hyphens.