Kaydet (Commit) ddadc1ee authored tarafından Michael Stahl's avatar Michael Stahl

tdf#80715: fix infinite loop in find-and-replace if SwTxtNode full

In a regex searching for "$" to remove the paragraph break, sw_JoinText()
may fail to join the nodes because the maximum size is reached; in this
case the cursor has to be moved to the next node, otherwise the search
will be stuck on that node forever.

This would fix the problem in LO 4.2 but it's actually rather harder to
trigger in 4.3+ because the 16-bit size limit of SwTxtNodes is gone.

(regression from b60ce846)

Change-Id: Ie047cad37835adf95afe0d12b94a16ff4aecb17a
üst 5a1fe97d
......@@ -583,9 +583,11 @@ int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
boost::scoped_ptr<OUString> pRepl( (bRegExp)
? ReplaceBackReferences( rSearchOpt, pCrsr ) : 0 );
rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange( *pCrsr,
(pRepl.get()) ? *pRepl : rSearchOpt.replaceString,
bRegExp );
bool const bReplaced =
rCursor.GetDoc()->getIDocumentContentOperations().ReplaceRange(
*pCrsr,
(pRepl.get()) ? *pRepl : rSearchOpt.replaceString,
bRegExp );
rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
if( bRegExp )
......@@ -599,7 +601,15 @@ int SwFindParaText::Find( SwPaM* pCrsr, SwMoveFn fnMove,
p->MoveTo( const_cast<SwPaM*>(pRegion) );
} while( p != pPrev );
}
pCrsr->Start()->nContent = nSttCnt;
if (bRegExp && !bReplaced)
{ // fdo#80715 avoid infinite loop if join failed
bool bRet = ((fnMoveForward == fnMove) ? &GoNextPara : &GoPrevPara)
(*pCrsr, fnMove);
(void) bRet;
assert(bRet); // if join failed, next node must be SwTxtNode
}
else
pCrsr->Start()->nContent = nSttCnt;
return FIND_NO_RING;
}
return bFnd ? FIND_FOUND : FIND_NOT_FOUND;
......
......@@ -3982,11 +3982,14 @@ bool DocumentContentOperationsManager::ReplaceRangeImpl( SwPaM& rPam, const OUSt
}
}
if( bJoinTxt )
::sw_JoinText( rPam, bJoinPrev );
bool bRet(true);
if (bJoinTxt)
{
bRet = ::sw_JoinText(rPam, bJoinPrev);
}
m_rDoc.getIDocumentState().SetModified();
return true;
return bRet;
}
SwFlyFrmFmt* DocumentContentOperationsManager::_InsNoTxtNode( const SwPosition& rPos, SwNoTxtNode* pNode,
......
......@@ -323,7 +323,7 @@ void sw_GetJoinFlags( SwPaM& rPam, bool& rJoinTxt, bool& rJoinPrev )
}
}
void sw_JoinText( SwPaM& rPam, bool bJoinPrev )
bool sw_JoinText( SwPaM& rPam, bool bJoinPrev )
{
SwNodeIndex aIdx( rPam.GetPoint()->nNode );
SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
......@@ -445,7 +445,9 @@ void sw_JoinText( SwPaM& rPam, bool bJoinPrev )
}
pTxtNd->JoinNext();
}
return true;
}
else return false;
}
static void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult& rResult,
......
......@@ -20,7 +20,7 @@
#ifndef INCLUDED_SW_SOURCE_CORE_INC_DOCEDT_HXX
#define INCLUDED_SW_SOURCE_CORE_INC_DOCEDT_HXX
void sw_JoinText( SwPaM& rPam, bool bJoinPrev );
bool sw_JoinText( SwPaM& rPam, bool bJoinPrev );
void sw_GetJoinFlags( SwPaM& rPam, bool& rJoinTxt, bool& rJoinPrev );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment