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 bcc5f7f8d059a1add749a0e10ef1113e51dbab50
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Nov 24 15:05:43 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Nov 25 09:37:51 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>
    (cherry picked from commit 9a7945f36ce95a48e0d525bc444e722b9ec5c452)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143171
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

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 afdb0cc27ce1..bf9e298ea4d2 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -937,6 +937,12 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf126426)
     }
 }
 
+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 c97e7229e829..2f7fda4b1388 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -7287,7 +7287,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() )
                 {
@@ -7349,30 +7348,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