sw/source/core/table/swnewtable.cxx |   29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

New commits:
commit ac8717e861608031e50230015c90e64282a10ad0
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Oct 7 16:21:27 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Oct 7 17:45:08 2022 +0200

    tdf#151375 sw: ODF import: delete any layout frames before ...
    
    ... converting subtables.
    
    This avoids use-after-free by the frames or a11y code on deleted cells.
    
    For file open, there is no layout at this point, but when inserting a
    file the crash happens.
    
    (regression from commit e366c928819c44b5c253c45dca6dae40b71c9808)
    
    Change-Id: Ia2cbe548fd5cdce7ae2479bfc3dc993ebb3ce830
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141080
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/table/swnewtable.cxx 
b/sw/source/core/table/swnewtable.cxx
index 8d6bcf023d2c..a0c420b1876c 100644
--- a/sw/source/core/table/swnewtable.cxx
+++ b/sw/source/core/table/swnewtable.cxx
@@ -2382,6 +2382,8 @@ bool SwTable::CanConvertSubtables() const
 
 void SwTable::ConvertSubtables()
 {
+    FndBox_ all(nullptr, nullptr);
+    all.DelFrames(*this); // tdf#151375 avoid UAF by frames on deleted cells
     for (size_t i = 0; i < GetTabLines().size(); ++i)
     {
         SwTableLine *const pLine(GetTabLines()[i]);
@@ -2397,6 +2399,7 @@ void SwTable::ConvertSubtables()
     }
     GCLines();
     m_bNewModel = true;
+    all.MakeFrames(*this);
 #if 0
     // note: outline nodes (and ordinary lists) are sorted by MoveNodes() 
itself
     //       (this could change order inside table of contents, but that's a
commit 4757dfc2a520f63fba0b27cc161fe732231dbd0e
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Oct 7 16:13:05 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Oct 7 17:44:54 2022 +0200

    tdf#145871 sw: ODF import: don't convert subtables if outer row ...
    
    ... has fixed or min height.
    
    The code had 2 obvious problems: the fixed height on the outer row
    wasn't cleared if the inner row didn't have a fixed height, and the code
    to set lastSize on the last row erroneously set the first row's height
    as well due to sharing the row format.
    
    But it turns out that this doesn't work anyway in case any of the inner
    rows are variable sized, because without layout it's not possible to
    determine the height of these rows, and so the lastSize is going to be
    too large in many cases.
    
    (regression from commit e366c928819c44b5c253c45dca6dae40b71c9808)
    
    Change-Id: I42ac7c14236562f9cae228efc0e98dc2fa8c2a23
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141079
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/table/swnewtable.cxx 
b/sw/source/core/table/swnewtable.cxx
index d87c039185c0..8d6bcf023d2c 100644
--- a/sw/source/core/table/swnewtable.cxx
+++ b/sw/source/core/table/swnewtable.cxx
@@ -2133,6 +2133,11 @@ void SwTable::ConvertSubtableBox(sal_uInt16 const nRow, 
sal_uInt16 const nBox)
     assert(!pSubTableBox->GetTabLines().empty());
     // are relative (%) heights possible? apparently not
     SwFormatFrameSize const 
outerSize(pSourceLine->GetFrameFormat()->GetFrameSize());
+    if (outerSize.GetHeightSizeType() != SwFrameSize::Variable)
+    {   // tdf#145871 clear fixed size in first row
+        pSourceLine->ClaimFrameFormat();
+        pSourceLine->GetFrameFormat()->ResetFormatAttr(RES_FRM_SIZE);
+    }
     tools::Long minHeights(0);
     {
         SwFrameFormat const& 
rSubLineFormat(*pSubTableBox->GetTabLines()[0]->GetFrameFormat());
@@ -2171,12 +2176,14 @@ void SwTable::ConvertSubtableBox(sal_uInt16 const nRow, 
sal_uInt16 const nBox)
             && outerSize.GetHeightSizeType() != SwFrameSize::Variable
             && minHeights < outerSize.GetHeight())
         {
+            assert(false); // this should be impossible currently, such 
subtable isn't converted because layout is needed to determine how much space 
is taken up by variable height rows
             SwFormatFrameSize 
lastSize(pNewLine->GetFrameFormat()->GetFrameSize());
             lastSize.SetHeight(lastSize.GetHeight() + outerSize.GetHeight() - 
minHeights);
             if (lastSize.GetHeightSizeType() == SwFrameSize::Variable)
             {
                 lastSize.SetHeightSizeType(SwFrameSize::Minimum);
             }
+            pNewLine->ClaimFrameFormat();
             pNewLine->GetFrameFormat()->SetFormatAttr(lastSize);
         }
         SfxPoolItem const* pRowBrush(nullptr);
@@ -2295,6 +2302,7 @@ bool SwTable::CanConvertSubtables() const
                     return false;
                 }
                 haveSubtable = true;
+                bool haveNonFixedInnerLine(false);
                 for (SwTableLine const*const pInnerLine : pBox->GetTabLines())
                 {
                     // bitmap row background will look different
@@ -2311,6 +2319,13 @@ bool SwTable::CanConvertSubtables() const
                             return false;
                         }
                     }
+                    if (SwFormatFrameSize const* pSize = 
rRowFormat.GetItemIfSet(RES_FRM_SIZE))
+                    {
+                        if (pSize->GetHeightSizeType() != SwFrameSize::Fixed)
+                        {
+                            haveNonFixedInnerLine = true;
+                        }
+                    }
                     for (SwTableBox const*const pInnerBox : 
pInnerLine->GetTabBoxes())
                     {
                         if (!pInnerBox->GetTabLines().empty())
@@ -2319,6 +2334,17 @@ bool SwTable::CanConvertSubtables() const
                         }
                     }
                 }
+                if (haveNonFixedInnerLine)
+                {
+                    if (SwFormatFrameSize const* pSize = 
pLine->GetFrameFormat()->GetItemIfSet(RES_FRM_SIZE))
+                    {
+                        if (pSize->GetHeightSizeType() != 
SwFrameSize::Variable)
+                        {
+                            // not possible to distribute fixed outer row 
height on rows without layout
+                            return false;
+                        }
+                    }
+                }
             }
         }
     }

Reply via email to