tdf#152200: tolerate begin/end fldChar context mismatch

We generate such files currently. Fixing that will be another commit.

Change-Id: I788501e346cba63c08a767c0e05e063bc1172089
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143223
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143255
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/sw/qa/extras/ooxmlimport/data/tdf152200-bad_fldChar_end.docx b/sw/qa/extras/ooxmlimport/data/tdf152200-bad_fldChar_end.docx
new file mode 100644
index 0000000..7f77c8d
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/tdf152200-bad_fldChar_end.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 62ae325..d96ca84 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -941,6 +941,12 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf119039)
    // Should not crash/hang because of problematic embedded compound
}

CPPUNIT_TEST_FIXTURE(Test, testTdf152200)
{
    load(mpTestDocumentPath, "tdf152200-bad_fldChar_end.docx");
    // Should not crash/hang because of wrong placement of ending fldChar
}

// tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index dabc55a..2c2e28d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -7465,7 +7465,6 @@ void DomainMapper_Impl::PopFieldContext()
        {
            try
            {
                uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
                uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY );
                if( xToInsert.is() )
                {
@@ -7527,30 +7526,38 @@ void DomainMapper_Impl::PopFieldContext()
                    }
                    else
                    {
                        uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
                        FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper());
                        if (pFormControlHelper)
                        {
                            uno::Reference< text::XFormField > xFormField( pContext->GetFormField() );
                            assert(xCrsr.is());
                            if (pFormControlHelper->hasFFDataHandler())
                            // xCrsr may be empty e.g. when pContext->GetStartRange() is outside of
                            // xTextAppend, like when a field started in a parent paragraph is being
                            // closed inside an anchored text box. It could be possible to throw an
                            // exception here, and abort import, but Word tolerates such invalid
                            // input, so it makes sense to do the same (tdf#152200)
                            if (xCrsr.is())
                            {
                                xToInsert.set(xFormField, uno::UNO_QUERY);
                                if (xFormField.is() && xToInsert.is())
                                uno::Reference< text::XFormField > xFormField(pContext->GetFormField());
                                if (pFormControlHelper->hasFFDataHandler())
                                {
                                    PopFieldmark(m_aTextAppendStack, xCrsr,
                                        pContext->GetFieldId());
                                    pFormControlHelper->processField( xFormField );
                                    xToInsert.set(xFormField, uno::UNO_QUERY);
                                    if (xFormField.is() && xToInsert.is())
                                    {
                                        PopFieldmark(m_aTextAppendStack, xCrsr,
                                                     pContext->GetFieldId());
                                        pFormControlHelper->processField(xFormField);
                                    }
                                    else
                                    {
                                        pFormControlHelper->insertControl(xCrsr);
                                    }
                                }
                                else
                                {
                                    pFormControlHelper->insertControl(xCrsr);
                                }
                            }
                            else
                            {
                                PopFieldmark(m_aTextAppendStack, xCrsr,
                                    PopFieldmark(m_aTextAppendStack, xCrsr,
                                        pContext->GetFieldId());
                                uno::Reference<lang::XComponent>(xFormField, uno::UNO_QUERY_THROW)->dispose(); // presumably invalid?
                                    uno::Reference<lang::XComponent>(xFormField, uno::UNO_QUERY_THROW)->dispose(); // presumably invalid?
                                }
                            }
                        }
                        else if (!pContext->GetHyperlinkURL().isEmpty() && xCrsr.is())