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)