writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx               |    6 ++
 writerfilter/qa/cppunittests/dmapper/data/fdo78333-1-minimized.docx |binary
 writerfilter/source/dmapper/DomainMapper.cxx                        |   26 
+++-------
 writerfilter/source/dmapper/SdtHelper.cxx                           |    1 
 4 files changed, 16 insertions(+), 17 deletions(-)

New commits:
commit a8ee639d256315e730bc4014dcca0d78f2de686f
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Wed Nov 22 11:59:09 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Nov 23 14:09:33 2023 +0100

    fix a regression crash from commit 5082d50
    
    The commit generated crashes in the crashtest documents
    7711 bugtrackers/docx/fdo78333-1.docx and
    695 forums/docx/forum-mso-en-4096.docx.
    This was due to "m_xFieldStartRange", the start of the text
    portion of the block SDT, being recorded too early. This led to
    including characters that shouldn't be there in the generated
    content control.
    This patch moves the calls to setFieldStartRange to just before
    the first appendTextPortion call.
    
    Change-Id: I7230346fee9a37ebac70beb9bcafd9d7b612eb00
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159816
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 7c4dba1deffd81f647a4a3be7a79f68f3bf9f1ba)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159761
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx
index 7cafcd19f280..ec771ba0f1b4 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper.cxx
@@ -149,6 +149,12 @@ CPPUNIT_TEST_FIXTURE(Test, testSdtBlockText)
     xContentControlProps->getPropertyValue("Alias") >>= aAlias;
     CPPUNIT_ASSERT_EQUAL(OUString("myalias"), aAlias);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFdo78333)
+{
+    // just care that it doesn't crash/assert
+    loadFromURL(u"fdo78333-1-minimized.docx");
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/fdo78333-1-minimized.docx 
b/writerfilter/qa/cppunittests/dmapper/data/fdo78333-1-minimized.docx
new file mode 100644
index 000000000000..0c4a5bc67288
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/fdo78333-1-minimized.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 0c5f5d855261..9f279469362f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1190,9 +1190,6 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                 m_pImpl->PushSdt();
                 break;
             }
-            if (m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::plainText
-                && GetCurrentTextRange().is())
-                
m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
             m_pImpl->SetSdt(true);
         }
         break;
@@ -4115,7 +4112,6 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
         {
             m_pImpl->m_pSdtHelper->createPlainTextControl();
             finishParagraph();
-            
m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
             return;
         }
     }
@@ -4369,10 +4365,9 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
                 m_pImpl->clearDeferredBreaks();
             }
 
-            bool bSdtBlockUnusedText
-                = m_pImpl->m_pSdtHelper->GetSdtType() != 
NS_ooxml::LN_CT_SdtRun_sdtContent
-                  && m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::plainText
-                  && m_pImpl->m_pSdtHelper->hasUnusedText();
+            bool bInSdtBlockText
+                = m_pImpl->m_pSdtHelper->GetSdtType() == 
NS_ooxml::LN_CT_SdtBlock_sdtContent
+                  && m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::plainText;
             if (pContext && pContext->GetFootnote().is())
             {
                 pContext->GetFootnote()->setLabel( sText );
@@ -4382,32 +4377,29 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, 
size_t len)
             }
             else if (m_pImpl->IsOpenFieldCommand() && 
!m_pImpl->IsForceGenericFields())
             {
-                if (bSdtBlockUnusedText)
+                if (bInSdtBlockText && m_pImpl->m_pSdtHelper->hasUnusedText())
                     m_pImpl->m_pSdtHelper->createPlainTextControl();
                 m_pImpl->AppendFieldCommand(sText);
-                if (bSdtBlockUnusedText)
-                    
m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
             }
             else if( m_pImpl->IsOpenField() && 
m_pImpl->IsFieldResultAsString())
             {
-                if (bSdtBlockUnusedText)
+                if (bInSdtBlockText && m_pImpl->m_pSdtHelper->hasUnusedText())
                     m_pImpl->m_pSdtHelper->createPlainTextControl();
                 /*depending on the success of the field insert operation this 
result will be
                   set at the field or directly inserted into the text*/
                 m_pImpl->AppendFieldResult(sText);
-                if (bSdtBlockUnusedText)
-                    
m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
             }
             else
             {
                 if (pContext == nullptr)
                     pContext = new PropertyMap();
 
+                if (bInSdtBlockText && !m_pImpl->m_pSdtHelper->hasUnusedText())
+                    
m_pImpl->m_pSdtHelper->setFieldStartRange(GetCurrentTextRange()->getEnd());
+
                 m_pImpl->appendTextPortion( sText, pContext );
 
-                if (m_pImpl->m_pSdtHelper->GetSdtType() == 
NS_ooxml::LN_CT_SdtBlock_sdtContent
-                    && m_pImpl->m_pSdtHelper->getControlType() == 
SdtControlType::plainText
-                    && !sText.isEmpty())
+                if (bInSdtBlockText && !sText.isEmpty())
                     m_pImpl->m_pSdtHelper->setHasUnusedText(true);
             }
 
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx 
b/writerfilter/source/dmapper/SdtHelper.cxx
index d56ea2f4873b..e1bbc5e9d8f9 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -601,6 +601,7 @@ void SdtHelper::clear()
     m_nId = 0;
     m_nTabIndex = 0;
     m_aLock.clear();
+    m_xFieldStartRange.clear();
 }
 
 void SdtHelper::SetPlaceholderDocPart(const OUString& rPlaceholderDocPart)

Reply via email to