[Libreoffice-commits] core.git: Branch 'libreoffice-5-4' - sw/qa sw/source

Caolán McNamara caolanm at redhat.com
Thu Feb 8 13:13:14 UTC 2018


 sw/qa/core/data/html/fail/ofz5909-1.html |    1 
 sw/source/core/doc/htmltbl.cxx           |    7 
 sw/source/filter/html/htmlftn.cxx        |   31 +--
 sw/source/filter/html/htmlnumreader.cxx  |   14 +
 sw/source/filter/html/htmlsect.cxx       |    6 
 sw/source/filter/html/htmltab.cxx        |  245 ++++++++++++++++++++++++++++---
 sw/source/filter/html/swhtml.cxx         |    6 
 sw/source/filter/html/swhtml.hxx         |   42 +++++
 sw/source/filter/html/wrthtml.hxx        |    4 
 9 files changed, 297 insertions(+), 59 deletions(-)

New commits:
commit 1c6311b3fe9bbbf978960167bd67cf8d51cd1f6e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jan 1 16:12:21 2018 +0000

    ofz#4767 Bad-cast
    
    Reviewed-on: https://gerrit.libreoffice.org/47235
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 5670a9619b77a6a9e53b0cf20c059ea66ca5f450)
    
    ofz: avoid deleting the table still being processed
    
    Reviewed-on: https://gerrit.libreoffice.org/46902
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit f297b0d043e0767d85f00aa1e4cae5b036b0ac51)
    
    ofz#4753 Bad-cast, check all open tables
    
    Reviewed-on: https://gerrit.libreoffice.org/47199
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 80fc91db239869b513f47866f45d8a43fb98fe16)
    
    CurrentTableInPaM->PendingTableInPaM
    
    (cherry picked from commit 2ed6eba4f99681fe717741ddc1534ed3ccc15e82)
    
    ofz#4848 Null-dereference READ
    
    (cherry picked from commit d4d0b1a2b9f11fb7629559e08c345697ba129c04)
    
    ofz#4817 Bad-cast
    
    Reviewed-on: https://gerrit.libreoffice.org/47236
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 9e269ef68e33fc9da154f6694be7cbcd5e3b4bfc)
    
    ofz#4872 Null-dereference READ
    
    we're going to need a bigger boat
    
    Reviewed-on: https://gerrit.libreoffice.org/47269
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit dfc72242e5bf67bdd5127bf38ed2ad5b3e49cea3)
    
    ofz#4971 Bad-cast
    
    Reviewed-on: https://gerrit.libreoffice.org/47466
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit c75c3b2fdab5614664215e52d85657472ec86f05)
    
    ofz#5007 Null-dereference READ
    
    Reviewed-on: https://gerrit.libreoffice.org/47537
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 6d05e0945054459ed04d50ae16731f933be48664)
    
    ofz#5235 Bad-cast
    
    Reviewed-on: https://gerrit.libreoffice.org/47747
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 710cf469bf0e43a021fc1a24a80745bc602368ef)
    
    ofz#5909 Null-dereference READ
    
    Reviewed-on: https://gerrit.libreoffice.org/49218
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 5090d575117fbe6ced75dc45c514f8d990523251)
    
    ofz#6064 clear footnotes from tobe-deleted paragraph
    
    Change-Id: Ibf8285efae7c570452954feb41a1a36bf44504a4
    a92d469fd0e280bdc6470e780ab12b00366f0f8d
    e6e2fb9f2e16e021a4719c418f52ce074c359904
    c8b48d3b3e3f87e9ac3e8a6bb832f8e8dfe8ab7d
    632aca7e3f59b7edf48c8c35eff4abf1946af652
    5dc9c66ce17f6401fbc9683cf8b10bf62755a166
    e4ee3ae1ac9f906ca3faec412bbafc0c6a911aaf
    cf66aa82e72a2b9f24f590b84bb0441ebf09463f
    830483071ce481fd14b0d1227c90e492e125f35e
    041f09f37941a92ccee3f0ebf9e5a950dee0c52f
    830d3e8bda517e7681cea7481c32457486ced693
    33f75adab35d43a4bbf51e33a0abcb5daeca93a3
    
    ofz: Null-deref
    
    Change-Id: I9992191fe5b4cfd771cc36a61d0ebaa8a9e6e9db
    Reviewed-on: https://gerrit.libreoffice.org/46743
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit e867b393ef95cb9bec7f68787771dfa329b00bea)
    
    ofz#4728 Null-deref
    
    Reviewed-on: https://gerrit.libreoffice.org/47000
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit f2e0c18cd44fff1e1b79924f582ced400fb00dad)
    
    Change-Id: Ide91a63424f864e2913b8268c4eca7961ba54572
    Reviewed-on: https://gerrit.libreoffice.org/49358
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>

diff --git a/sw/qa/core/data/html/fail/ofz5909-1.html b/sw/qa/core/data/html/fail/ofz5909-1.html
new file mode 100644
index 000000000000..9511b2bc1eac
--- /dev/null
+++ b/sw/qa/core/data/html/fail/ofz5909-1.html
@@ -0,0 +1 @@
+<table><td><a class="sdfootnoteanc"href=" sdfootnote1   "></a><div id="sdfootnote1"><table><td>
\ No newline at end of file
diff --git a/sw/source/core/doc/htmltbl.cxx b/sw/source/core/doc/htmltbl.cxx
index 9f9e6fdfeac1..dcfed6c3f04c 100644
--- a/sw/source/core/doc/htmltbl.cxx
+++ b/sw/source/core/doc/htmltbl.cxx
@@ -561,10 +561,9 @@ void SwHTMLTableLayout::AutoLayoutPass1()
                             nIdx++;
                         }
                     }
-                    else
+                    else if (SwHTMLTableLayout *pChild = pCnts->GetTable())
                     {
                         OSL_ENSURE( false, "Sub tables in HTML import?" );
-                        SwHTMLTableLayout *pChild = pCnts->GetTable();
                         pChild->AutoLayoutPass1();
                         sal_uLong nMaxTableCnts = pChild->m_nMax;
                         sal_uLong nAbsMinTableCnts = pChild->m_nMin;
@@ -1608,7 +1607,7 @@ void SwHTMLTableLayout::SetWidths( bool bCallPass2, sal_uInt16 nAbsAvail,
                 {
                     SetBoxWidth( pBox, j, pCell->GetColSpan() );
                 }
-                else
+                else if (SwHTMLTableLayout *pTable = pContents->GetTable())
                 {
                     sal_uInt16 nAbs = 0, nRel = 0, nLSpace = 0, nRSpace = 0,
                            nInhSpace = 0;
@@ -1620,7 +1619,7 @@ void SwHTMLTableLayout::SetWidths( bool bCallPass2, sal_uInt16 nAbsAvail,
                         nRSpace = GetRightCellSpace( j, nColSpan );
                         nInhSpace = GetInhCellSpace( j, nColSpan );
                     }
-                    pContents->GetTable()->SetWidths( bCallPass2, nAbs, nRel,
+                    pTable->SetWidths( bCallPass2, nAbs, nRel,
                                                     nLSpace, nRSpace,
                                                     nInhSpace );
                 }
diff --git a/sw/source/filter/html/htmlftn.cxx b/sw/source/filter/html/htmlftn.cxx
index 9f2fea2a1743..272d04f8ddeb 100644
--- a/sw/source/filter/html/htmlftn.cxx
+++ b/sw/source/filter/html/htmlftn.cxx
@@ -31,17 +31,6 @@
 #include "swhtml.hxx"
 #include "wrthtml.hxx"
 
-struct SwHTMLFootEndNote_Impl
-{
-    SwHTMLTextFootnotes aTextFootnotes;
-    std::vector<OUString> aNames;
-
-    OUString sName;
-    OUString sContent;            // Infos fuer die letzte Fussnote
-    bool bEndNote;
-    bool bFixed;
-};
-
 sal_Int32 lcl_html_getNextPart( OUString& rPart, const OUString& rContent,
                              sal_Int32 nPos )
 {
@@ -209,11 +198,8 @@ void SwHTMLParser::FinishFootEndNote()
         m_pPam->GetNode().GetTextNode()->GetTextAttrForCharAt(
             m_pPam->GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_FTN ) );
     // In header and footer no footnotes can be inserted.
-    if( pTextFootnote )
-    {
-        m_pFootEndNoteImpl->aTextFootnotes.push_back( pTextFootnote );
-        m_pFootEndNoteImpl->aNames.push_back(m_pFootEndNoteImpl->sName);
-    }
+    if (pTextFootnote)
+        m_pFootEndNoteImpl->aTextFootnotes.push_back(SwHTMLTextFootnote(m_pFootEndNoteImpl->sName,pTextFootnote));
     m_pFootEndNoteImpl->sName = aEmptyOUStr;
     m_pFootEndNoteImpl->sContent = aEmptyOUStr;
     m_pFootEndNoteImpl->bFixed = false;
@@ -235,19 +221,18 @@ SwNodeIndex *SwHTMLParser::GetFootEndNoteSection( const OUString& rName )
 {
     SwNodeIndex *pStartNodeIdx = nullptr;
 
-    if( m_pFootEndNoteImpl )
+    if (m_pFootEndNoteImpl)
     {
         OUString aName(rName.toAsciiUpperCase());
 
-        size_t nCount = m_pFootEndNoteImpl->aNames.size();
+        size_t nCount = m_pFootEndNoteImpl->aTextFootnotes.size();
         for(size_t i = 0; i < nCount; ++i)
         {
-            if(m_pFootEndNoteImpl->aNames[i] == aName)
+            if (m_pFootEndNoteImpl->aTextFootnotes[i].sName == aName)
             {
-                pStartNodeIdx = m_pFootEndNoteImpl->aTextFootnotes[i]->GetStartNode();
-                m_pFootEndNoteImpl->aNames.erase(m_pFootEndNoteImpl->aNames.begin() + i);
+                pStartNodeIdx = m_pFootEndNoteImpl->aTextFootnotes[i].pTextFootnote->GetStartNode();
                 m_pFootEndNoteImpl->aTextFootnotes.erase( m_pFootEndNoteImpl->aTextFootnotes.begin() + i );
-                if(m_pFootEndNoteImpl->aNames.empty())
+                if (m_pFootEndNoteImpl->aTextFootnotes.empty())
                 {
                     delete m_pFootEndNoteImpl;
                     m_pFootEndNoteImpl = nullptr;
@@ -288,7 +273,7 @@ Writer& OutHTML_SwFormatFootnote( Writer& rWrt, const SfxPoolItem& rHt )
     }
 
     if( !rHTMLWrt.m_pFootEndNotes )
-        rHTMLWrt.m_pFootEndNotes = new SwHTMLTextFootnotes;
+        rHTMLWrt.m_pFootEndNotes = new std::vector<SwTextFootnote*>;
     rHTMLWrt.m_pFootEndNotes->insert( rHTMLWrt.m_pFootEndNotes->begin() + nPos, pTextFootnote );
 
     OStringBuffer sOut;
diff --git a/sw/source/filter/html/htmlnumreader.cxx b/sw/source/filter/html/htmlnumreader.cxx
index 3b4ae766bdd3..3a17e18bce30 100644
--- a/sw/source/filter/html/htmlnumreader.cxx
+++ b/sw/source/filter/html/htmlnumreader.cxx
@@ -470,6 +470,13 @@ void SwHTMLParser::NewNumBulListItem( HtmlTokenId nToken )
         AppendTextNode( AM_NOSPACE, false );
     m_bNoParSpace = false;    // no space in <LI>!
 
+    SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode();
+    if (!pTextNode)
+    {
+        SAL_WARN("sw.html", "No Text-Node at PaM-Position");
+        return;
+    }
+
     const bool bCountedInList = nToken != HtmlTokenId::LISTHEADER_ON;
 
     HTMLAttrContext *pCntxt = new HTMLAttrContext( nToken );
@@ -505,7 +512,6 @@ void SwHTMLParser::NewNumBulListItem( HtmlTokenId nToken )
         m_nOpenParaToken = nToken;
     }
 
-    SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode();
     static_cast<SwContentNode *>(pTextNode)->SetAttr( SwNumRuleItem(aNumRuleName) );
     pTextNode->SetAttrListLevel(nLevel);
     // #i57656# - <IsCounted()> state of text node has to be adjusted accordingly.
@@ -599,7 +605,11 @@ void SwHTMLParser::EndNumBulListItem( HtmlTokenId nToken, bool bSetColl )
 void SwHTMLParser::SetNodeNum( sal_uInt8 nLevel )
 {
     SwTextNode* pTextNode = m_pPam->GetNode().GetTextNode();
-    OSL_ENSURE( pTextNode, "No Text-Node at PaM-Position" );
+    if (!pTextNode)
+    {
+        SAL_WARN("sw.html", "No Text-Node at PaM-Position");
+        return;
+    }
 
     OSL_ENSURE( GetNumInfo().GetNumRule(), "No numbering rule" );
     const OUString& rName = GetNumInfo().GetNumRule()->GetName();
diff --git a/sw/source/filter/html/htmlsect.cxx b/sw/source/filter/html/htmlsect.cxx
index b1151ca37313..ae36ae1870c8 100644
--- a/sw/source/filter/html/htmlsect.cxx
+++ b/sw/source/filter/html/htmlsect.cxx
@@ -195,7 +195,11 @@ void SwHTMLParser::NewDivision( HtmlTokenId nToken )
                 static_cast<const SwStartNode *>( &rContentStIdx.GetNode() );
             aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1;
 
-            m_xDoc->getIDocumentContentOperations().DelFullPara( aDelPam );
+            if (!PendingObjectsInPaM(aDelPam))
+            {
+                ClearFootnotesInRange(aDelPam.GetMark()->nNode, aDelPam.GetPoint()->nNode);
+                m_xDoc->getIDocumentContentOperations().DelFullPara(aDelPam);
+            }
 
             // update page style
             for( size_t i=0; i < m_xDoc->GetPageDescCnt(); i++ )
diff --git a/sw/source/filter/html/htmltab.cxx b/sw/source/filter/html/htmltab.cxx
index e033e4f36c61..6d80b324b885 100644
--- a/sw/source/filter/html/htmltab.cxx
+++ b/sw/source/filter/html/htmltab.cxx
@@ -35,6 +35,7 @@
 #include <svl/urihelper.hxx>
 #include <o3tl/make_unique.hxx>
 
+#include <dcontact.hxx>
 #include <fmtornt.hxx>
 #include <frmfmt.hxx>
 #include <fmtfsize.hxx>
@@ -58,6 +59,7 @@
 #include "swhtml.hxx"
 #include "swcss1.hxx"
 #include <numrule.hxx>
+#include <txtftn.hxx>
 
 #define NETSCAPE_DFLT_BORDER 1
 #define NETSCAPE_DFLT_CELLSPACING 2
@@ -617,6 +619,8 @@ public:
 
     void IncBoxCount() { m_nBoxes++; }
     bool IsOverflowing() const { return m_nBoxes > 64000; }
+
+    bool PendingDrawObjectsInPaM(SwPaM& rPam) const;
 };
 
 void HTMLTableCnts::InitCtor()
@@ -1075,10 +1079,14 @@ HTMLTable::HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
 
     for( sal_uInt16 i=0; i<m_nCols; i++ )
         m_pColumns->push_back(o3tl::make_unique<HTMLTableColumn>());
+
+    m_pParser->RegisterHTMLTable(this);
 }
 
 HTMLTable::~HTMLTable()
 {
+    m_pParser->DeregisterHTMLTable(this);
+
     delete m_pResizeDrawObjects;
     delete m_pDrawObjectPrcWidths;
 
@@ -1714,9 +1722,9 @@ SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper,
             pBox = NewTableBox( pCnts->GetStartNode(), pUpper );
             pCnts->SetTableBox( pBox );
         }
-        else
+        else if (HTMLTable* pTable = pCnts->GetTable())
         {
-            pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
+            pTable->InheritVertBorders( this, nLeftCol,
                                                    nRightCol-nLeftCol );
             // ... that's a table. We'll build a new box and put the rows of the table
             // in the rows of the box
@@ -1729,6 +1737,10 @@ SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper,
             pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace, nRSpace,
                                           nInhSpace );
         }
+        else
+        {
+            return nullptr;
+        }
     }
     else
     {
@@ -2405,6 +2417,12 @@ void HTMLTable::MakeTable( SwTableBox *pBox, sal_uInt16 nAbsAvail,
             break;
         }
 
+        if (!m_pSwTable)
+        {
+            SAL_WARN("sw.html", "no table");
+            return;
+        }
+
         // get the table format and adapt it
         SwFrameFormat *pFrameFormat = m_pSwTable->GetFrameFormat();
         pFrameFormat->SetFormatAttr( SwFormatHoriOrient(0,eHoriOri) );
@@ -3594,6 +3612,7 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions,
                 const SwTable* pSwTable = m_xDoc->InsertTable(
                         SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
                         *m_pPam->GetPoint(), 1, 1, text::HoriOrientation::LEFT );
+                SwFrameFormat *pFrameFormat = pSwTable ? pSwTable->GetFrameFormat() : nullptr;
 
                 if( bForceFrame )
                 {
@@ -3603,22 +3622,20 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions,
                 }
                 else
                 {
-                    if( bStyleParsed )
+                    if (bStyleParsed && pFrameFormat)
                     {
                         m_pCSS1Parser->SetFormatBreak( aItemSet, aPropInfo );
-                        pSwTable->GetFrameFormat()->SetFormatAttr( aItemSet );
+                        pFrameFormat->SetFormatAttr( aItemSet );
                     }
                     m_pPam->Move( fnMoveBackward );
                 }
 
                 SwNode const*const pNd = & m_pPam->GetPoint()->nNode.GetNode();
-                if( !bAppended && !bForceFrame )
-                {
-                    SwTextNode *const pOldTextNd =
-                        pSavePos->nNode.GetNode().GetTextNode();
-                    OSL_ENSURE( pOldTextNd, "Why we aren't in a text node?" );
-                    SwFrameFormat *pFrameFormat = pSwTable->GetFrameFormat();
+                SwTextNode *const pOldTextNd = (!bAppended && !bForceFrame) ?
+                    pSavePos->nNode.GetNode().GetTextNode() : nullptr;
 
+                if (pFrameFormat && pOldTextNd)
+                {
                     const SfxPoolItem* pItem2;
                     if( SfxItemState::SET == pOldTextNd->GetSwAttrSet()
                             .GetItemState( RES_PAGEDESC, false, &pItem2 ) &&
@@ -3931,15 +3948,21 @@ void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, bool bReadOptions,
             InsertTableSection( static_cast< sal_uInt16 >(pSaveStruct->IsHeaderCell()
                                         ? RES_POOLCOLL_TABLE_HDLN
                                         : RES_POOLCOLL_TABLE ));
-        const SwEndNode *pEndNd = pStNd->EndOfSectionNode();
-        SwContentNode *pCNd = m_xDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetContentNode();
-        //Added defaults to CJK and CTL
-        SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
-        pCNd->SetAttr( aFontHeight );
-        SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
-        pCNd->SetAttr( aFontHeightCJK );
-        SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
-        pCNd->SetAttr( aFontHeightCTL );
+
+        if (!pStNd)
+            eState = SvParserState::Error;
+        else
+        {
+            const SwEndNode *pEndNd = pStNd->EndOfSectionNode();
+            SwContentNode *pCNd = m_xDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetContentNode();
+            //Added defaults to CJK and CTL
+            SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
+            pCNd->SetAttr( aFontHeight );
+            SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
+            pCNd->SetAttr( aFontHeightCJK );
+            SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
+            pCNd->SetAttr( aFontHeightCTL );
+        }
 
         pSaveStruct->AddContents( new HTMLTableCnts(pStNd) );
         pSaveStruct->ClearIsInSection();
@@ -4972,6 +4995,134 @@ HTMLTableOptions::HTMLTableOptions( const HTMLOptions& rOptions,
     }
 }
 
+namespace
+{
+    class FrameDeleteWatch : public SwClient
+    {
+        SwFrameFormat* m_pObjectFormat;
+        bool m_bDeleted;
+    public:
+        FrameDeleteWatch(SwFrameFormat* pObjectFormat)
+            : m_pObjectFormat(pObjectFormat)
+            , m_bDeleted(false)
+        {
+            if (m_pObjectFormat)
+                m_pObjectFormat->Add(this);
+
+        }
+
+        virtual void SwClientNotify(const SwModify& rModify, const SfxHint& rHint) override
+        {
+            SwClient::SwClientNotify(rModify, rHint);
+            if (auto pDrawFrameFormatHint = dynamic_cast<const sw::DrawFrameFormatHint*>(&rHint))
+            {
+                if (pDrawFrameFormatHint->m_eId == sw::DrawFrameFormatHintId::DYING)
+                {
+                    m_pObjectFormat->Remove(this);
+                    m_bDeleted = true;
+                }
+            }
+        }
+
+        bool WasDeleted() const
+        {
+            return m_bDeleted;
+        }
+
+        virtual ~FrameDeleteWatch() override
+        {
+            if (!m_bDeleted && m_pObjectFormat)
+                m_pObjectFormat->Remove(this);
+        }
+    };
+
+    class IndexInRange
+    {
+    private:
+        SwNodeIndex maStart;
+        SwNodeIndex maEnd;
+    public:
+        explicit IndexInRange(const SwNodeIndex& rStart, const SwNodeIndex& rEnd)
+            : maStart(rStart)
+            , maEnd(rEnd)
+        {
+        }
+        bool operator()(const SwHTMLTextFootnote& rTextFootnote) const
+        {
+            const SwNodeIndex aTextIdx(rTextFootnote.pTextFootnote->GetTextNode());
+            return aTextIdx >= maStart && aTextIdx <= maEnd;
+        }
+    };
+}
+
+void SwHTMLParser::ClearFootnotesInRange(const SwNodeIndex& rMkNdIdx, const SwNodeIndex& rPtNdIdx)
+{
+    //similarly for footnotes
+    if (m_pFootEndNoteImpl)
+    {
+        m_pFootEndNoteImpl->aTextFootnotes.erase(std::remove_if(m_pFootEndNoteImpl->aTextFootnotes.begin(),
+            m_pFootEndNoteImpl->aTextFootnotes.end(), IndexInRange(rMkNdIdx, rPtNdIdx)), m_pFootEndNoteImpl->aTextFootnotes.end());
+        if (m_pFootEndNoteImpl->aTextFootnotes.empty())
+        {
+            delete m_pFootEndNoteImpl;
+            m_pFootEndNoteImpl = nullptr;
+        }
+    }
+
+    //follow DelFlyInRange pattern here
+    const bool bDelFwrd = rMkNdIdx.GetIndex() <= rPtNdIdx.GetIndex();
+
+    SwDoc* pDoc = rMkNdIdx.GetNode().GetDoc();
+    SwFrameFormats& rTable = *pDoc->GetSpzFrameFormats();
+    for ( auto i = rTable.size(); i; )
+    {
+        SwFrameFormat *pFormat = rTable[--i];
+        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
+        SwPosition const*const pAPos = rAnch.GetContentAnchor();
+        if (pAPos &&
+            ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) ||
+             (rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR)) &&
+            ( bDelFwrd
+                ? rMkNdIdx < pAPos->nNode && pAPos->nNode <= rPtNdIdx
+                : rPtNdIdx <= pAPos->nNode && pAPos->nNode < rMkNdIdx ))
+        {
+            if( rPtNdIdx != pAPos->nNode )
+            {
+                // If the Fly is deleted, all Flys in its content have to be deleted too.
+                const SwFormatContent &rContent = pFormat->GetContent();
+                // But only fly formats own their content, not draw formats.
+                if (rContent.GetContentIdx() && pFormat->Which() == RES_FLYFRMFMT)
+                {
+                    ClearFootnotesInRange(*rContent.GetContentIdx(),
+                                          SwNodeIndex(*rContent.GetContentIdx()->GetNode().EndOfSectionNode()));
+                }
+            }
+        }
+    }
+}
+
+void SwHTMLParser::DeleteSection(SwStartNode* pSttNd)
+{
+    //if section to be deleted contains a pending m_pMarquee, it will be deleted
+    //so clear m_pMarquee pointer if that's the case
+    SwFrameFormat* pObjectFormat = m_pMarquee ? ::FindFrameFormat(m_pMarquee) : nullptr;
+    FrameDeleteWatch aWatch(pObjectFormat);
+
+    //similarly for footnotes
+    SwNodeIndex aSttIdx(*pSttNd), aEndIdx(*pSttNd->EndOfSectionNode());
+    ClearFootnotesInRange(aSttIdx, aEndIdx);
+
+    m_xDoc->getIDocumentContentOperations().DeleteSection(pSttNd);
+
+    if (pObjectFormat)
+    {
+        if (aWatch.WasDeleted())
+            m_pMarquee = nullptr;
+        else
+            pObjectFormat->Remove(&aWatch);
+    }
+}
+
 HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
                                      bool bIsParentHead,
                                      bool bHasParentSection,
@@ -5186,7 +5337,7 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
                 // The section isn't needed anymore
                 m_pPam->SetMark();
                 m_pPam->DeleteMark();
-                m_xDoc->getIDocumentContentOperations().DeleteSection( const_cast<SwStartNode *>(pCapStNd) );
+                DeleteSection(const_cast<SwStartNode*>(pCapStNd));
                 m_pTable->SetCaption( nullptr, false );
             }
 
@@ -5205,8 +5356,9 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
             m_bUpperSpace = true;
             SetTextCollAttrs();
 
-            m_nParaCnt = m_nParaCnt - std::min(m_nParaCnt,
-                pTCntxt->GetTableNode()->GetTable().GetTabSortBoxes().size());
+            SwTableNode* pTableNode = pTCntxt->GetTableNode();
+            size_t nTableBoxSize = pTableNode ? pTableNode->GetTable().GetTabSortBoxes().size() : 0;
+            m_nParaCnt = m_nParaCnt - std::min(m_nParaCnt, nTableBoxSize);
 
             // Jump to a table if needed
             if( JUMPTO_TABLE == m_eJumpTo && m_pTable->GetSwTable() &&
@@ -5235,7 +5387,7 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
         {
             m_pPam->SetMark();
             m_pPam->DeleteMark();
-            m_xDoc->getIDocumentContentOperations().DeleteSection( const_cast<SwStartNode *>(pCapStNd) );
+            DeleteSection(const_cast<SwStartNode*>(pCapStNd));
             pCurTable->SetCaption( nullptr, false );
         }
     }
@@ -5253,4 +5405,51 @@ HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
     return pRetTable;
 }
 
+bool HTMLTable::PendingDrawObjectsInPaM(SwPaM& rPam) const
+{
+    if (!m_pResizeDrawObjects)
+        return false;
+
+    bool bRet = false;
+
+    sal_uInt16 nCount = m_pResizeDrawObjects->size();
+    for (sal_uInt16 i = 0; i < nCount && !bRet; ++i)
+    {
+        SdrObject *pObj = (*m_pResizeDrawObjects)[i];
+        SwFrameFormat* pObjectFormat = ::FindFrameFormat(pObj);
+        if (!pObjectFormat)
+            continue;
+        const SwFormatAnchor& rAnch = pObjectFormat->GetAnchor();
+        if (const SwPosition* pPos = rAnch.GetContentAnchor())
+        {
+            SwNodeIndex aObjNodeIndex(pPos->nNode);
+            bRet = (aObjNodeIndex >= rPam.Start()->nNode && aObjNodeIndex <= rPam.End()->nNode);
+        }
+    }
+
+    return bRet;
+}
+
+bool SwHTMLParser::PendingObjectsInPaM(SwPaM& rPam) const
+{
+    bool bRet = false;
+    for (const auto& a : m_aTables)
+    {
+        bRet = a->PendingDrawObjectsInPaM(rPam);
+        if (bRet)
+            break;
+        const SwTable *pTable = a->GetSwTable();
+        if (!pTable)
+            continue;
+        const SwTableNode* pTableNode = pTable->GetTableNode();
+        if (!pTableNode)
+            continue;
+        SwNodeIndex aTableNodeIndex(*pTableNode);
+        bRet = (aTableNodeIndex >= rPam.Start()->nNode && aTableNodeIndex <= rPam.End()->nNode);
+        if (bRet)
+            break;
+    }
+    return bRet;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
index f3560b11fbb6..5150785c3111 100644
--- a/sw/source/filter/html/swhtml.cxx
+++ b/sw/source/filter/html/swhtml.cxx
@@ -1446,10 +1446,10 @@ void SwHTMLParser::NextToken( HtmlTokenId nToken )
         if( !aToken.isEmpty() && ' '==aToken[0] && !IsReadPRE() )
         {
             sal_Int32 nPos = m_pPam->GetPoint()->nContent.GetIndex();
-            if( nPos )
+            const SwTextNode* pTextNode = nPos ? m_pPam->GetPoint()->nNode.GetNode().GetTextNode() : nullptr;
+            if (pTextNode)
             {
-                const OUString& rText =
-                    m_pPam->GetPoint()->nNode.GetNode().GetTextNode()->GetText();
+                const OUString& rText = pTextNode->GetText();
                 sal_Unicode cLast = rText[--nPos];
                 if( ' ' == cLast || '\x0a' == cLast)
                     aToken = aToken.copy(1);
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index 5284590f9f0f..dcb616636054 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -404,6 +404,7 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient
     SwNodeIndex     *m_pSttNdIdx;
 
     HTMLTable       *m_pTable;      // current "outermost" table
+    std::vector<HTMLTable*> m_aTables;
     SwHTMLForm_Impl *m_pFormImpl;   // current form
     SdrObject       *m_pMarquee;    // current marquee
     SwField         *m_pField;      // current field
@@ -643,6 +644,10 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient
     // tags realized via character styles
     void NewCharFormat( HtmlTokenId nToken );
 
+    void ClearFootnotesInRange(const SwNodeIndex& rSttIdx, const SwNodeIndex& rEndIdx);
+
+    void DeleteSection(SwStartNode* pSttNd);
+
     // <SDFIELD>
 public:
     static SvxNumType GetNumType( const OUString& rStr, SvxNumType eDfltType );
@@ -857,6 +862,8 @@ private:
     bool HasCurrentParaFlys( bool bNoSurroundOnly = false,
                              bool bSurroundOnly = false ) const;
 
+    bool PendingObjectsInPaM(SwPaM& rPam) const;
+
 public:         // used in tables
 
     // Create brush item (with new) or 0
@@ -894,6 +901,18 @@ public:
 
     virtual bool ParseMetaOptions( const css::uno::Reference<css::document::XDocumentProperties>&,
             SvKeyValueIterator* ) override;
+
+
+    void RegisterHTMLTable(HTMLTable* pNew)
+    {
+        m_aTables.push_back(pNew);
+    }
+
+    void DeregisterHTMLTable(HTMLTable* pOld)
+    {
+        m_aTables.erase(std::remove(m_aTables.begin(), m_aTables.end(), pOld));
+    }
+
 };
 
 struct SwPendingStackData
@@ -973,6 +992,29 @@ inline void SwHTMLParser::PushContext( HTMLAttrContext *pCntxt )
     m_aContexts.push_back( pCntxt );
 }
 
+class SwTextFootnote;
+
+struct SwHTMLTextFootnote
+{
+    OUString sName;
+    SwTextFootnote* pTextFootnote;
+    SwHTMLTextFootnote(const OUString &rName, SwTextFootnote* pInTextFootnote)
+        : sName(rName)
+        , pTextFootnote(pInTextFootnote)
+    {
+    }
+};
+
+struct SwHTMLFootEndNote_Impl
+{
+    std::vector<SwHTMLTextFootnote> aTextFootnotes;
+
+    OUString sName;
+    OUString sContent;            // information for the last footnote
+    bool bEndNote;
+    bool bFixed;
+};
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index 6061bd4c2eec..afbd9b1a7c68 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -59,8 +59,6 @@ class SwHTMLPosFlyFrames;
 class SwTextFootnote;
 enum class HtmlPosition;
 
-typedef std::vector<SwTextFootnote*> SwHTMLTextFootnotes;
-
 extern SwAttrFnTab aHTMLAttrFnTab;
 
 #define HTML_PARSPACE (MM50)
@@ -286,7 +284,7 @@ public:
     SwHTMLFormatInfos m_CharFormatInfos;
     SwHTMLFormatInfos m_TextCollInfos;
     std::vector<SwFormatINetFormat*> m_aINetFormats; // the "open" INet attributes
-    SwHTMLTextFootnotes *m_pFootEndNotes;
+    std::vector<SwTextFootnote*> *m_pFootEndNotes;
 
     OUString m_aCSS1Selector;           // style selector
     OUString m_aNonConvertableCharacters;


More information about the Libreoffice-commits mailing list