diff --git a/sw/qa/extras/layout/data/tdf164098.fodt b/sw/qa/extras/layout/data/tdf164098.fodt new file mode 100644 index 000000000000..2ce8c7dff3c2 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf164098.fodt @@ -0,0 +1,116 @@ + + + 2024-11-29T22:06:13.3429325682024-12-02T12:01:13.042657312PT22M9S16LibreOfficeDev/25.2.0.0.alpha1$Linux_X86_64 LibreOffice_project/654e3134adbf48c61aaa29dcd9f52ce236694535 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + متن مـــــــــتــــــــن متن + + + \ No newline at end of file diff --git a/sw/qa/extras/layout/layout4.cxx b/sw/qa/extras/layout/layout4.cxx index d1527e503961..36af7e749aae 100644 --- a/sw/qa/extras/layout/layout4.cxx +++ b/sw/qa/extras/layout/layout4.cxx @@ -1886,6 +1886,18 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf152839_firstRows) CPPUNIT_ASSERT_EQUAL(sal_Int32(223), nHeight); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf164098) +{ + createSwDoc("tdf164098.fodt"); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + + pWrtShell->StartOfSection(false); + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect*/ false, 6, /*bBasicCall*/ false); + + // Without the fix, this line will cause a freeze: + pWrtShell->Insert(u"ـ"_ustr); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx index 893f08392ef9..05f62d9ebefa 100644 --- a/sw/source/core/text/itradj.cxx +++ b/sw/source/core/text/itradj.cxx @@ -185,7 +185,14 @@ static bool lcl_CheckKashidaPositions(SwScriptInfo& rSI, SwTextSizeInfo& rInf, S if (stKashidaPos.has_value()) { TextFrameIndex nNewKashidaPos{ aScanner.GetBegin() + stKashidaPos->nIndex }; - aNewKashidaPositions.push_back(nNewKashidaPos); + + // tdf#164098: The above algorithm can return out-of-range kashida positions. This + // can happen if, for example, a single word is split across multiple lines, and + // the best kashida candidate position is on the first line. + if (nNewKashidaPos >= nIdx && nNewKashidaPos < nEnd) + { + aNewKashidaPositions.push_back(nNewKashidaPos); + } } } }