tdf#157937 sw: fix freezing of cycle case on tracked changes

Add loop control to avoid never-ending iteration on selected
text with tracked changes, where transliteration can result
empty strings.

Regression since commit 2d3c77e9b10f20091ef338e262ba7756eb280ce9
"tdf#109266 sw change tracking: track transliteration".

Change-Id: Ia5f92adfdda33562b4d1abe72c51134be8304639
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158525
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/uiwriter/data/tdf130088.docx b/sw/qa/extras/uiwriter/data/tdf130088.docx
new file mode 100644
index 0000000..8d5a7a6
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf130088.docx
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx
index dd0b1d6..53f6dce 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -663,6 +663,33 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf113790)
    CPPUNIT_ASSERT(dynamic_cast<SwXTextDocument*>(mxComponent.get()));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157937)
{
    createSwDoc("tdf130088.docx");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();

    // select paragraph
    pWrtShell->SelPara(nullptr);

    // enable redlining
    dispatchCommand(mxComponent, ".uno:TrackChanges", {});
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());

    // show changes
    CPPUNIT_ASSERT_MESSAGE(
        "redlines should be visible",
        IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));

    // cycle case with change tracking
    dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
    dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});

    // This resulted freezing
    dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf108048)
{
    createSwDoc();
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 71ee1fd..2f3e7aa 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1973,6 +1973,7 @@ void SwTextNode::TransliterateText(

        sal_Int32 nEndPos = 0;
        LanguageType nLang = LANGUAGE_NONE;
        sal_Int32 nLoopControlRuns = 0;
        do {
            if( pIter )
            {
@@ -2005,7 +2006,13 @@ void SwTextNode::TransliterateText(
            }

            nStt = nEndPos;
        } while( nEndPos < nEnd && pIter && pIter->Next() );

            // tdf#157937 selection containing tracked changes needs loop control:
            // stop looping, if there are too much empty transliterations
            if ( sChgd.isEmpty() )
                ++nLoopControlRuns;

        } while( nEndPos < nEnd && pIter && pIter->Next() && nLoopControlRuns < 100 );
    }

    if (aChanges.empty())