sw/qa/extras/ooxmlexport/data/tdf170438_dropdown.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport25.cxx           |   12 ++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx         |    6 ++++--
 3 files changed, 16 insertions(+), 2 deletions(-)

New commits:
commit f5e64db444b5cd5cdb53b2744bd52d441a0169b3
Author:     Justin Luth <[email protected]>
AuthorDate: Thu Jan 22 13:22:17 2026 -0500
Commit:     Justin Luth <[email protected]>
CommitDate: Mon Jan 26 17:56:25 2026 +0100

    tdf#170438 docx export: never export listItem with empty displayText
    
    MS Word was reporting a document as corrupt
    after LO round-tripped it with an empty displayText.
    However, an empty w:value is not a 'corrupt' result.
    
    Note that this situation was possible also while importing DOCX.
    We don't always import SDTs as content controls (e.g. in tables).
    In that case, only the 'values' are considered,
    so an empty entry is created in the dropdown field,
    which then got exported as an empty displayText.
    
    make CppunitTest_sw_ooxmlexport25 \
        CPPUNIT_TEST_NAME=testTdf170438_dropdown
    
    ooxmlexport13's tdf119809.docx is a VML shape
    that is called a combobox, and it exported
    with WritePostponedFormControl.
    It sounds like it can only have 'values' when added by a VBA macro,
    so likely these will almost never output a displayText.
    
    Change-Id: Ib306eda90b4179e10402c276e7c47a3bfdd83cfb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197867
    Reviewed-by: Justin Luth <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 270fe90efbb275a670d063303e395ed88ea4731d)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198157

diff --git a/sw/qa/extras/ooxmlexport/data/tdf170438_dropdown.odt 
b/sw/qa/extras/ooxmlexport/data/tdf170438_dropdown.odt
new file mode 100644
index 000000000000..02bbe360bf25
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf170438_dropdown.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx
index 009b92a1d663..49e0ba96bedc 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx
@@ -147,6 +147,18 @@ DECLARE_OOXMLEXPORT_TEST(testTdf165478_bottomAligned, 
"tdf165478_bottomAligned.d
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1887), nFlyTop);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf170438_dropdown)
+{
+    createSwDoc("tdf170438_dropdown.odt");
+
+    saveAndReload(TestFilter::DOCX);
+
+    xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
+    // MS Word reports document as corrupt if displayText is empty
+    assertXPath(pXmlDoc, "//w:listItem[1]", "displayText", u" ");
+    assertXPath(pXmlDoc, "//w:listItem[1]", "value", u""); // value may be 
empty
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf170389_manyTabstops)
 {
     createSwDoc("tdf170389_manyTabstops.odt");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 0673a2601423..286ce3a077da 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2887,9 +2887,10 @@ void DocxAttributeOutput::WriteSdtDropDownStart(
     for (auto const& rItem : rListItems)
     {
         auto const item(OUStringToOString(rItem, RTL_TEXTENCODING_UTF8));
+        OString sDisplayText = item.isEmpty() ? " "_ostr : item; // 
displayText must not be empty
         m_pSerializer->singleElementNS(XML_w, XML_listItem,
                 FSNS(XML_w, XML_value), item,
-                FSNS(XML_w, XML_displayText), item);
+                FSNS(XML_w, XML_displayText), sDisplayText);
     }
 
     m_pSerializer->endElementNS(XML_w, XML_dropDownList);
@@ -5899,8 +5900,9 @@ void DocxAttributeOutput::WritePostponedFormControl(const 
SdrObject* pObject)
 
         for (const auto& rItem : aItems)
         {
+            OUString sDisplayText = rItem.isEmpty() ? " " : rItem; // 
displayText must not be empty
             m_pSerializer->singleElementNS(XML_w, XML_listItem,
-                                           FSNS(XML_w, XML_displayText), rItem,
+                                           FSNS(XML_w, XML_displayText), 
sDisplayText,
                                            FSNS(XML_w, XML_value), rItem);
         }
 

Reply via email to