sw/qa/extras/ooxmlimport/data/tdf152200-bad_fldChar_end.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx                    |    6 +
 writerfilter/source/dmapper/DomainMapper_Impl.cxx            |   39 ++++++-----
 3 files changed, 29 insertions(+), 16 deletions(-)

New commits:
commit b2237449bec85903f438454ac925574f3856d8c6
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Nov 24 15:05:43 2022 +0300
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 28 12:34:22 2022 +0100

    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.kagan...@collabora.com>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143255
    Reviewed-by: Michael Stahl <michael.st...@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 000000000000..7f77c8d66b2b
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf152200-bad_fldChar_end.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 62ae3250af73..d96ca84ab720 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 dabc55a89c55..2c2e28def4ee 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())

Reply via email to