sw/qa/core/data/ww6/pass/ofz42330-1.doc |binary
 sw/source/filter/ww8/ww8par.cxx         |   66 +++++++++++++++++++++-----------
 sw/source/filter/ww8/ww8par.hxx         |   42 ++++++++++++++------
 sw/source/filter/ww8/ww8par6.cxx        |    8 +--
 4 files changed, 77 insertions(+), 39 deletions(-)

New commits:
commit d8a4713e57bcb2b243743c03f3a5fc735c5e636c
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Mon Dec 13 11:16:39 2021 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Dec 13 15:11:03 2021 +0100

    ofz#42330 Use-of-unintialized-value
    
    Change-Id: I7281aa335ebeb86afb47aeb31da30933ada7d4bd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126732
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/qa/core/data/ww6/pass/ofz42330-1.doc 
b/sw/qa/core/data/ww6/pass/ofz42330-1.doc
new file mode 100644
index 000000000000..a1cd04f53d67
Binary files /dev/null and b/sw/qa/core/data/ww6/pass/ofz42330-1.doc differ
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index a23d4ee4ece4..634bd13aac8a 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4025,7 +4025,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
     tools::Long nCpOfs = m_xPlcxMan->GetCpOfs(); // Offset for Header/Footer, 
Footnote
 
     WW8_CP nNext = m_xPlcxMan->Where();
-    m_pPreviousNode = nullptr;
+    m_xPreviousNode.reset();
     sal_uInt8 nDropLines = 0;
     SwCharFormat* pNewSwCharFormat = nullptr;
     const SwCharFormat* pFormat = nullptr;
@@ -4057,7 +4057,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
 
         // If the previous paragraph was a dropcap then do not
         // create a new txtnode and join the two paragraphs together
-        if (bStartLine && !m_pPreviousNode) // Line end
+        if (bStartLine && !m_xPreviousNode) // Line end
         {
             bool bSplit = true;
             if (m_bCareFirstParaEndInToc)
@@ -4078,10 +4078,10 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
             }
         }
 
-        if (m_pPreviousNode && bStartLine)
+        if (SwTextNode* pPreviousNode = (bStartLine && m_xPreviousNode) ? 
m_xPreviousNode->GetTextNode() : nullptr)
         {
             SwTextNode* pEndNd = m_pPaM->GetNode().GetTextNode();
-            const sal_Int32 nDropCapLen = 
m_pPreviousNode->GetText().getLength();
+            const sal_Int32 nDropCapLen = pPreviousNode->GetText().getLength();
 
             // Need to reset the font size and text position for the dropcap
             {
@@ -4108,12 +4108,12 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
             SwPosition aStart(*pEndNd);
             m_xCtrlStck->NewAttr(aStart, aDrop);
             m_xCtrlStck->SetAttr(*m_pPaM->GetPoint(), RES_PARATR_DROP);
-            m_pPreviousNode = nullptr;
+            m_xPreviousNode.reset();
         }
         else if (m_bDropCap)
         {
             // If we have found a dropcap store the textnode
-            m_pPreviousNode = m_pPaM->GetNode().GetTextNode();
+            m_xPreviousNode.reset(new 
TextNodeListener(m_pPaM->GetNode().GetTextNode()));
 
             SprmResult aDCS;
             if (m_bVer67)
@@ -4124,7 +4124,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
             if (aDCS.pSprm && aDCS.nRemainingData >= 1)
                 nDropLines = (*aDCS.pSprm) >> 3;
             else    // There is no Drop Cap Specifier hence no dropcap
-                m_pPreviousNode = nullptr;
+                m_xPreviousNode.reset();
 
             SprmResult aDistance = m_xPlcxMan->GetPapPLCF()->HasSprm(0x842F);
             if (aDistance.pSprm && aDistance.nRemainingData >= 2)
@@ -4196,7 +4196,7 @@ bool SwWW8ImplReader::ReadText(WW8_CP nStartCp, WW8_CP 
nTextLen, ManTypes nType)
         }
     }
 
-    m_pPreviousNode = nullptr;
+    m_xPreviousNode.reset();
 
     if (m_pPaM->GetPoint()->nContent.GetIndex())
         AppendTextNode(*m_pPaM->GetPoint());
@@ -4307,7 +4307,6 @@ SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, 
SotStorage* pStorage,
     , m_bLoadingTOXCache(false)
     , m_nEmbeddedTOXLevel(0)
     , m_bLoadingTOXHyperlink(false)
-    , m_pPreviousNode(nullptr)
     , m_bCareFirstParaEndInToc(false)
     , m_bCareLastParaEndInToc(false)
     , m_bNotifyMacroEventRead(false)
@@ -4685,9 +4684,9 @@ void wwExtraneousParas::delete_all_from_doc()
     auto aEnd = m_aTextNodes.rend();
     for (auto aI = m_aTextNodes.rbegin(); aI != aEnd; ++aI)
     {
-        const TextNodeListener& rListener = *aI;
-        SwTextNode *pTextNode = rListener.m_pTextNode;
-        pTextNode->Remove(const_cast<TextNodeListener*>(&rListener));
+        ExtraTextNodeListener& rListener = 
const_cast<ExtraTextNodeListener&>(*aI);
+        SwTextNode* pTextNode = rListener.GetTextNode();
+        rListener.StopListening(pTextNode);
 
         SwNodeIndex aIdx(*pTextNode);
         SwPaM aTest(aIdx);
@@ -4698,24 +4697,33 @@ void wwExtraneousParas::delete_all_from_doc()
 
 void wwExtraneousParas::insert(SwTextNode *pTextNode)
 {
-    auto it = m_aTextNodes.emplace(pTextNode, this).first;
-    const TextNodeListener& rListener = *it;
-    pTextNode->Add(const_cast<TextNodeListener*>(&rListener));
+    m_aTextNodes.emplace(pTextNode, this);
 }
 
 void wwExtraneousParas::remove_if_present(SwModify* pModify)
 {
     auto it = std::find_if(m_aTextNodes.begin(), m_aTextNodes.end(),
-        [pModify](const wwExtraneousParas::TextNodeListener& rEntry) { return 
rEntry.m_pTextNode == pModify; });
+        [pModify](const ExtraTextNodeListener& rEntry) { return 
rEntry.GetTextNode() == pModify; });
     if (it == m_aTextNodes.end())
         return;
     SAL_WARN("sw.ww8", "It is unexpected to drop a para scheduled for 
removal");
-    const TextNodeListener& rListener = *it;
-    pModify->Remove(const_cast<TextNodeListener*>(&rListener));
     m_aTextNodes.erase(it);
 }
 
-void wwExtraneousParas::TextNodeListener::SwClientNotify(const SwModify& 
rModify, const SfxHint& rHint)
+TextNodeListener::TextNodeListener(SwTextNode* pTextNode)
+    : m_pTextNode(pTextNode)
+{
+    m_pTextNode->Add(this);
+}
+
+TextNodeListener::~TextNodeListener()
+{
+    if (!m_pTextNode)
+        return;
+    StopListening(m_pTextNode);
+}
+
+void TextNodeListener::SwClientNotify(const SwModify& rModify, const SfxHint& 
rHint)
 {
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
@@ -4724,9 +4732,23 @@ void 
wwExtraneousParas::TextNodeListener::SwClientNotify(const SwModify& rModify
     // before wwExtraneousParas gets its chance to do so. Not the usual 
scenario,
     // indicates an underlying bug.
     if (pLegacy->GetWhich() == RES_OBJECTDYING)
-    {
-        m_pOwner->remove_if_present(const_cast<SwModify*>(&rModify));
-    }
+        removed(const_cast<SwModify*>(&rModify));
+}
+
+void TextNodeListener::StopListening(SwModify* pTextNode)
+{
+    pTextNode->Remove(this);
+    m_pTextNode = nullptr;
+}
+
+void TextNodeListener::removed(SwModify* pTextNode)
+{
+    StopListening(pTextNode);
+}
+
+void wwExtraneousParas::ExtraTextNodeListener::removed(SwModify* pTextNode)
+{
+    m_pOwner->remove_if_present(pTextNode);
 }
 
 void SwWW8ImplReader::StoreMacroCmds()
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 9dfd0a702f0f..4315dbc15716 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -889,6 +889,25 @@ public:
     sal_uInt32 GetTextAreaWidth() const;
 };
 
+class TextNodeListener : public SwClient
+{
+protected:
+    SwTextNode *m_pTextNode;
+
+    virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
+
+public:
+    TextNodeListener(SwTextNode* pTextNode);
+    bool operator<(const TextNodeListener& rOther) const
+    {
+        return m_pTextNode->GetIndex() < rOther.m_pTextNode->GetIndex();
+    }
+    void StopListening(SwModify* pTextNode);
+    SwTextNode* GetTextNode() const { return m_pTextNode; }
+    virtual void removed(SwModify* pTextNode);
+    virtual ~TextNodeListener() override;
+};
+
 //Various writer elements like frames start off containing a blank paragraph,
 //sometimes this paragraph turns out to be extraneous, e.g. the frame should
 //only contain a table with no trailing paragraph.
@@ -904,26 +923,23 @@ public:
 class wwExtraneousParas
 {
 private:
-    struct TextNodeListener : public SwClient
+    class ExtraTextNodeListener : public TextNodeListener
     {
-        TextNodeListener(SwTextNode* pTextNode, wwExtraneousParas* pOwner)
-            : m_pTextNode(pTextNode)
+    private:
+        wwExtraneousParas* m_pOwner;
+    public:
+        ExtraTextNodeListener(SwTextNode* pTextNode, wwExtraneousParas* pOwner)
+            : TextNodeListener(pTextNode)
             , m_pOwner(pOwner)
         {
         }
-        bool operator<(const TextNodeListener& rOther) const
-        {
-            return m_pTextNode->GetIndex() < rOther.m_pTextNode->GetIndex();
-        }
-        virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
-
-        SwTextNode *m_pTextNode;
-        wwExtraneousParas* m_pOwner;
+        virtual void removed(SwModify* pTextNode) override;
     };
+
     /*
     A vector of SwTextNodes to erase from a document after import is complete
     */
-    std::set<TextNodeListener> m_aTextNodes;
+    std::set<ExtraTextNodeListener> m_aTextNodes;
     SwDoc& m_rDoc;
 
     void remove_if_present(SwModify* pModify);
@@ -1381,7 +1397,7 @@ private:
     // a document position recorded the after-position of TOC section, managed 
by Read_F_TOX() and End_Field()
     std::unique_ptr<SwPaM> m_pPosAfterTOC;
     // used for some dropcap tweaking
-    SwTextNode* m_pPreviousNode;
+    std::unique_ptr<TextNodeListener> m_xPreviousNode;
 
     std::unique_ptr< SwPosition > m_pLastAnchorPos;
 
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index c9fc7df8a8ef..9473fca42e45 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -2562,7 +2562,7 @@ bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool 
bStealAttr)
         if (bStealAttr)
             m_xCtrlStck->StealAttr(rPam.GetPoint()->nNode);
 
-        if (m_pLastAnchorPos || m_pPreviousNode || (m_xSFlyPara && 
m_xSFlyPara->xMainTextPos))
+        if (m_pLastAnchorPos || m_xPreviousNode || (m_xSFlyPara && 
m_xSFlyPara->xMainTextPos))
         {
             SwNodeIndex aToBeJoined(aPref, 1);
 
@@ -2580,12 +2580,12 @@ bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool 
bStealAttr)
                     m_pLastAnchorPos.reset();
             }
 
-            if (m_pPreviousNode)
+            if (m_xPreviousNode)
             {
                 //If the drop character start pos is here, then clear it.
-                SwNodeIndex aDropCharPos(*m_pPreviousNode);
+                SwNodeIndex aDropCharPos(*m_xPreviousNode->GetTextNode());
                 if (aDropCharPos == aToBeJoined)
-                    m_pPreviousNode = nullptr;
+                    m_xPreviousNode.reset();
             }
 
             if (m_xSFlyPara && m_xSFlyPara->xMainTextPos)

Reply via email to