xmloff/qa/unit/text.cxx                 |   20 +++++++++
 xmloff/source/text/XMLRedlineExport.cxx |   68 +++++++++++++++++---------------
 2 files changed, 58 insertions(+), 30 deletions(-)

New commits:
commit 5248afb9b630b5902936ea8a2f5c87248cb36dd3
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Sep 12 08:38:32 2025 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Sep 12 10:32:46 2025 +0200

    tdf#168321 sw format redline, direct: fix ODF strict export
    
    Save the bugdoc in strict ODF, the exporter crashes due to an assertion
    failure.
    
    What happens is that strict ODF doesn't add the loext namespace alias to
    the alias list, so we crash when we would write an loext attribute.
    
    Fix the problem by simply throwing away the direct format of a format
    redline when saving to strict ODF, just to please the validator.
    
    If we're at it, also don't register the direct format of the format
    redline in the autostyle pool in that case, since it would be
    unreferenced anyway.
    
    Change-Id: I0de9ee114be9ef67f97716cf5fd9aaa9f8757683
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190851
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx
index a82e62ac6e30..f6f4821cb97e 100644
--- a/xmloff/qa/unit/text.cxx
+++ b/xmloff/qa/unit/text.cxx
@@ -29,6 +29,8 @@
 #include <unotools/tempfile.hxx>
 #include <docmodel/uno/UnoTheme.hxx>
 #include <docmodel/theme/Theme.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <unotools/saveopt.hxx>
 
 using namespace ::com::sun::star;
 
@@ -1373,6 +1375,24 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, 
testRedlineFormatCharStyleExport)
     CPPUNIT_ASSERT_EQUAL(u"Strong_20_Emphasis"_ustr, aStyleName);
 }
 
+CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testRedlineFormatCharPropsStrictExport)
+{
+    // Given a document with a format redline, the redline contains the old 
char props:
+    SetODFDefaultVersion(SvtSaveOptions::ODFDefaultVersion::ODFVER_014);
+    comphelper::ScopeGuard g([] { 
SetODFDefaultVersion(SvtSaveOptions::ODFVER_LATEST); });
+    loadFromFile(u"redline-format-char-props.docx");
+
+    // When exporting the document to ODT strict:
+    save(u"writer8"_ustr);
+
+    // Then make sure no loext attribute is written:
+    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
+    // Without the accompanying fix in place, this test would have failed in 
an assertion in
+    // SvXMLNamespaceMap::GetQNameByKey().
+    assertXPathNoAttribute(pXmlDoc, 
"//text:tracked-changes/text:changed-region/text:format-change",
+                           "style-name");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/XMLRedlineExport.cxx 
b/xmloff/source/text/XMLRedlineExport.cxx
index f85d9671878b..3fdec09b8610 100644
--- a/xmloff/source/text/XMLRedlineExport.cxx
+++ b/xmloff/source/text/XMLRedlineExport.cxx
@@ -262,17 +262,21 @@ void XMLRedlineExport::ExportChangeAutoStyle(
         rExport.GetTextParagraphExport()->collectTextAutoStyles(xText);
     }
 
-    // See if the format redline has an autostyle for old direct formatting: 
if so, export that as
-    // an autostyle.
-    aAny = rPropSet->getPropertyValue(u"RedlineAutoFormat"_ustr);
-    uno::Reference<beans::XPropertySet> xAutoFormat;
-    aAny >>= xAutoFormat;
-    if (xAutoFormat.is())
-    {
-        // Check for parent style when declaring the automatic style.
-        rExport.GetTextParagraphExport()->Add(XmlStyleFamily::TEXT_TEXT, 
xAutoFormat,
-                                              /*aAddStates=*/{},
-                                              /*bCheckParent=*/true);
+    SvtSaveOptions::ODFSaneDefaultVersion eVersion = 
rExport.getSaneDefaultVersion();
+    if (eVersion & SvtSaveOptions::ODFSVER_EXTENDED)
+    {
+        // See if the format redline has an autostyle for old direct 
formatting: if so, export that as
+        // an autostyle.
+        aAny = rPropSet->getPropertyValue(u"RedlineAutoFormat"_ustr);
+        uno::Reference<beans::XPropertySet> xAutoFormat;
+        aAny >>= xAutoFormat;
+        if (xAutoFormat.is())
+        {
+            // Check for parent style when declaring the automatic style.
+            rExport.GetTextParagraphExport()->Add(XmlStyleFamily::TEXT_TEXT, 
xAutoFormat,
+                    /*aAddStates=*/{},
+                    /*bCheckParent=*/true);
+        }
     }
 }
 
@@ -367,27 +371,31 @@ void XMLRedlineExport::ExportChangedRegion(
         OUString sType;
         aAny >>= sType;
 
-        // See if the format redline has an autostyle for old direct 
formatting: if so, refer to the
-        // already exported autostyle.
-        aAny = rPropSet->getPropertyValue(u"RedlineAutoFormat"_ustr);
-        uno::Reference<beans::XPropertySet> xAutoStyle;
-        aAny >>= xAutoStyle;
-        if (xAutoStyle.is())
+        SvtSaveOptions::ODFSaneDefaultVersion eVersion = 
rExport.getSaneDefaultVersion();
+        if (eVersion & SvtSaveOptions::ODFSVER_EXTENDED)
         {
-            bool bIsUICharStyle;
-            bool bHasAutoStyle;
-            OUString aParentName;
-            uno::Reference<beans::XPropertySetInfo> xPropSetInfo = 
xAutoStyle->getPropertySetInfo();
-            if (xPropSetInfo->hasPropertyByName("CharStyleName"))
-            {
-                // Consider parent style when referring to the declared 
automatic style.
-                xAutoStyle->getPropertyValue("CharStyleName") >>= aParentName;
-            }
-            OUString sStyle = rExport.GetTextParagraphExport()->FindTextStyle(
-                xAutoStyle, bIsUICharStyle, bHasAutoStyle, 
/*pAddState=*/nullptr, &aParentName);
-            if (!sStyle.isEmpty())
+            // See if the format redline has an autostyle for old direct 
formatting: if so, refer to the
+            // already exported autostyle.
+            aAny = rPropSet->getPropertyValue(u"RedlineAutoFormat"_ustr);
+            uno::Reference<beans::XPropertySet> xAutoStyle;
+            aAny >>= xAutoStyle;
+            if (xAutoStyle.is())
             {
-                rExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_STYLE_NAME, 
rExport.EncodeStyleName(sStyle));
+                bool bIsUICharStyle;
+                bool bHasAutoStyle;
+                OUString aParentName;
+                uno::Reference<beans::XPropertySetInfo> xPropSetInfo = 
xAutoStyle->getPropertySetInfo();
+                if (xPropSetInfo->hasPropertyByName("CharStyleName"))
+                {
+                    // Consider parent style when referring to the declared 
automatic style.
+                    xAutoStyle->getPropertyValue("CharStyleName") >>= 
aParentName;
+                }
+                OUString sStyle = 
rExport.GetTextParagraphExport()->FindTextStyle(
+                        xAutoStyle, bIsUICharStyle, bHasAutoStyle, 
/*pAddState=*/nullptr, &aParentName);
+                if (!sStyle.isEmpty())
+                {
+                    rExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_STYLE_NAME, 
rExport.EncodeStyleName(sStyle));
+                }
             }
         }
 

Reply via email to