editeng/source/editeng/impedit2.cxx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
New commits: commit d7c2f3dfe78c91cb7610cc71545f822481235595 Author: Miklos Vajna <[email protected]> AuthorDate: Fri Jan 30 13:08:27 2026 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Fri Jan 30 17:00:51 2026 +0100 editeng: fix crash in ImpEditEngine::GetXPos() gdb backtrace on the core file from the crashreport: #5 0x0000000000afc0ee in std::__glibcxx_assert_fail(char const*, int, char const*, char const*) () #6 0x00007078315a78ff in std::vector<double, std::allocator<double> >::operator[] (this=<optimized out>, __n=<optimized out>) at /opt/rh/devtoolset-12/root/usr/include/c++/12/bits/stl_vector.h:1140 #7 std::vector<double, std::allocator<double> >::operator[] (this=<optimized out>, __n=<optimized out>) at /opt/rh/devtoolset-12/root/usr/include/c++/12/bits/stl_vector.h:1140 #8 ImpEditEngine::GetXPos (this=this@entry=0x3e8745e0, rParaPortion=..., rLine=..., nIndex=-18, bPreferPortionStart=<optimized out>) at editeng/source/editeng/impedit2.cxx:4303 #9 0x00007078315a79f6 in ImpEditEngine::GetEditCursor (this=this@entry=0x3e8745e0, rPortion=..., rLine=..., nIndex=<optimized out>, aFlags=aFlags@entry=...) at editeng/source/editeng/impedit2.cxx:3113 and: #8 ImpEditEngine::GetXPos (this=this@entry=0x3e8745e0, rParaPortion=..., rLine=..., nIndex=-18, bPreferPortionStart=<optimized out>) at editeng/source/editeng/impedit2.cxx:4303 4303 nPortionTextWidth = rLine.GetCharPosArray()[nTextPortionStart + rPortion.GetLen() - 1 - rLine.GetStart()]; (gdb) print rLine.maPositions $1 = std::vector of length 1, capacity 1 = {171.307373046875} (gdb) print nTextPortionStart $2 = 0 (gdb) print rPortion $3 = (const TextPortion &) @0x3b3cc250: {xExtraInfos = std::unique_ptr<ExtraPortionInfo> = {get() = 0x0}, nLen = 38, aOutSz = {<SizeTemplate<Size>> = {<SizeTemplateBase> = {<Pair> = { mnA = 5661, mnB = 344}, <No data fields>}, <No data fields>}, <No data fields>}, nKind = PortionKind::TEXT, nRightToLeftLevel = 0 ' (gdb) print rLine $4 = (const EditLine &) @0x3e968420: {maPositions = std::vector of length 1, capacity 1 = {171.307373046875}, maKashidaPositions = std::vector of length 0, capacity 0, mnTextWidth = 171, mnStartPosX = 3443, mnNextLinePosXDiff = 0, mnStart = 39, mnEnd = 40, mnStartPortion = 2, mnEndPortion = 2, mnHeight = 344, mnTextHeight = 344, mnMaxAscent = 265, mbHangingPunctuation = false, mbInvalid = true} Seeing nPortionTextWidth is updated conditionally, also require to only update if the array index would be inside the array bounds. Change-Id: I98adbc55187f0221534bc358755e51160cdb992b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198436 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index b983334a00e2..4e09872f23a2 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -4618,7 +4618,18 @@ tools::Long ImpEditEngine::GetXPos(ParaPortion const& rParaPortion, EditLine con // But the array might not be init yet, if using text ranger this method is called within CreateLines()... tools::Long nPortionTextWidth = rPortion.GetSize().Width(); if ( ( rPortion.GetKind() == PortionKind::TEXT ) && rPortion.GetLen() && !GetTextRanger() ) - nPortionTextWidth = rLine.GetCharPosArray()[nTextPortionStart + rPortion.GetLen() - 1 - rLine.GetStart()]; + { + sal_Int32 nCharPosArrayIndex = nTextPortionStart + rPortion.GetLen() - 1 - rLine.GetStart(); + if (nCharPosArrayIndex >= 0 + && o3tl::make_unsigned(nCharPosArrayIndex) < rLine.GetCharPosArray().size()) + { + nPortionTextWidth = rLine.GetCharPosArray()[nCharPosArrayIndex]; + } + else + { + SAL_WARN("editeng", "ImpEditEngine::GetXPos: out of bounds access to rLine.GetCharPosArray()"); + } + } if ( nTextPortionStart != nIndex ) {
