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 )
     {

Reply via email to