From 42754477886f6a12afbabfd2a64d8c787a57bc03 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 18 Jul 2024 10:49:08 +0200 Subject: [PATCH] Fix panic in link linebreaking (#4579) --- crates/typst/src/layout/inline/linebreak.rs | 12 +++++------- tests/ref/issue-hyphenate-in-link.png | Bin 0 -> 1200 bytes tests/suite/layout/inline/linebreak.typ | 8 ++++++++ 3 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 tests/ref/issue-hyphenate-in-link.png diff --git a/crates/typst/src/layout/inline/linebreak.rs b/crates/typst/src/layout/inline/linebreak.rs index 075d24b33..1f30bb732 100644 --- a/crates/typst/src/layout/inline/linebreak.rs +++ b/crates/typst/src/layout/inline/linebreak.rs @@ -655,9 +655,9 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) { let (head, tail) = text.split_at(last); if head.ends_with("://") || tail.starts_with("www.") { let (link, _) = link_prefix(tail); - let end = last + link.len(); linebreak_link(link, |i| f(last + i, Breakpoint::Normal)); - while iter.peek().is_some_and(|&p| p < end) { + last += link.len(); + while iter.peek().is_some_and(|&p| p < last) { iter.next(); } } @@ -687,19 +687,17 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) { }; // Hyphenate between the last and current breakpoint. - if hyphenate { - let mut offset = last; + if hyphenate && last < point { for segment in text[last..point].split_word_bounds() { if !segment.is_empty() && segment.chars().all(char::is_alphabetic) { - hyphenations(p, &lb, offset, segment, &mut f); + hyphenations(p, &lb, last, segment, &mut f); } - offset += segment.len(); + last += segment.len(); } } // Call `f` for the UAX #14 break opportunity. f(point, breakpoint); - last = point; } } diff --git a/tests/ref/issue-hyphenate-in-link.png b/tests/ref/issue-hyphenate-in-link.png new file mode 100644 index 0000000000000000000000000000000000000000..932c23ae994d61febff645f091481cdf34f4fbfb GIT binary patch literal 1200 zcmV;h1W)^kP) z*Mh8bZ=chzE8CMp?PKoiapYqV9W|$=Zqe1Ll1BTAL}sht+>8-BHqlC7h6cg0aUSZl;wW9IcrV+I|h3r$Fd85VAMEv$-kt^dQ zYsQXh*m<*c*@PL|6WG(t`_uU!yU7)NL6vXJ>9_5-t!^v0p)c zbhpL5U>FV-quqvpvLi&*TZ53w2f$WSzzJq0<%8#TT}c z``U-tRq$q$tD|}=BXfJaJzJY6zrvgBvQ)f+3)H&NT5hzN$$Y8>Wr>LX~G%=?1gXX=t=i@q(k~-sx+*#5RWbr*|2Rf2+ z>t-_`K^6dpV92M-WmC^oO@Xv;Mw52d@r7Dn_Q|f{0*~2b50=z>^ zTXC#n=14&M-gNMFsn}tRxO$u-Sw;@mEC`UMVa^csx>PxhhKSmP%b4;Ky?uG20gqHv zJ6UloR3?v{kL=gQKZA+*GEuyj^U6Gc*1Uag{S^sVOBhltp9XFVN3)xN+udbZo>d?L z0s3zUoY2)AxKy>0fI7z#q8jfKRDUW_n_zE1!sH*>9_PYwW2Mt*bcy${*-$PdbHZqJ z?9yow6W>I>gLLRyWs|ojAcLNnZhleBEVxh+1bNF-~t8GZ|IUHNg zrib2K-^0Qy1Y2&Kd=K9i5$u)Vdl>n-TCenFz`$sqf4TgyANIrld-xCNHj=Q(`<8|P O0000