[Libreoffice-commits] core.git: sw/qa sw/source

Justin Luth (via logerrit) logerrit at kemper.freedesktop.org
Tue Mar 31 07:40:09 UTC 2020


 sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx                        |   28 ++++++++++
 sw/source/filter/ww8/docxexport.cxx                              |   23 ++++++--
 3 files changed, 47 insertions(+), 4 deletions(-)

New commits:
commit 41dbdc1499f4512941a38e5972d03d26a2397a89
Author:     Justin Luth <justin.luth at collabora.com>
AuthorDate: Tue Mar 10 22:30:02 2020 +0300
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Mar 31 09:39:33 2020 +0200

    related tdf#106843 docxexport: if not enforced, let Writer protect
    
    The problem was that sections, etc., could not be protected
    if the document previously had some kind of protection
    that was now disabled/not enforced.
    
    Docx has a special flag that actually enables the selected
    protection (forms/track changes/readonly). Even if it isn't
    enabled, grabbagging keeps the "suggestion" for next time
    when the user wants to enable protection.
    
    "If the value of this element is off, 0, or false, all the
    WordprocessingML pertaining to document protection
    is still preserved in the document, but is not enforced."
    
    If the user requested some kind of protection in Writer,
    it should be able to override a grabbag "suggestion" and
    set a real protection value.
    
    Change-Id: I638c6420bfb9a1801187f3e16586d2e18dfacb84
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90322
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_luth at sil.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx b/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx
new file mode 100644
index 000000000000..143799ddb6bd
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf120852_readOnlyUnProtected.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index 7eb17d725845..a1b7ef6aad3b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -124,6 +124,34 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo79008, "fdo79008.docx")
      parseExport("word/document.xml");
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf120852_readOnlyUnProtected, "tdf120852_readOnlyUnProtected.docx")
+{
+
+    // Readonly is not enforced, just a suggestion,
+    // so when a section is protected, the document should enable forms protection.
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    CPPUNIT_ASSERT(!pTextDoc->GetDocShell()->IsSecurityOptOpenReadOnly());
+
+    uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY_THROW);
+    uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY_THROW);
+    const sal_Int32 nLastSection = xSections->getCount() - 1;
+    uno::Reference<beans::XPropertySet> xSect(xSections->getByIndex(nLastSection), uno::UNO_QUERY_THROW);
+    if ( !mbExported )
+    {
+        CPPUNIT_ASSERT_MESSAGE("Section is not protected", !getProperty<bool>(xSect, "IsProtected"));
+        // Enable section protection. The round-trip should have forms protection enabled.
+        xSect->setPropertyValue("IsProtected", uno::makeAny(true));
+    }
+    else
+    {
+        CPPUNIT_ASSERT_MESSAGE("Section is protected", getProperty<bool>(xSect, "IsProtected"));
+        xmlDocPtr pXmlSettings = parseExport("word/settings.xml");
+        assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "edit", "forms");
+        assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "enforcement", "true");
+    }
+}
+
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testAuthorPropertySdt, "author-property.docx")
 {
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 9aa7a8a2a083..ae63a3e13a2c 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1084,15 +1084,25 @@ void DocxExport::WriteSettings()
     uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
 
     bool hasProtectionProperties = false;
+    bool bWriterWantsToProtect = false;
+    bool bWriterWantsToProtectForm = false;
+    bool bWriterWantsToProtectRedline = false;
     bool bHasRedlineProtectionKey = false;
     bool bHasDummyRedlineProtectionKey = false;
     uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
+    if ( m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM) ||
+         m_pSections->DocumentIsProtected() )
+    {
+        bWriterWantsToProtect = bWriterWantsToProtectForm = true;
+    }
     if ( xPropSetInfo->hasPropertyByName( "RedlineProtectionKey" ) )
     {
         uno::Sequence<sal_Int8> aKey;
         xPropSet->getPropertyValue( "RedlineProtectionKey" ) >>= aKey;
         bHasRedlineProtectionKey = aKey.hasElements();
         bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1;
+        if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey )
+            bWriterWantsToProtect = bWriterWantsToProtectRedline = true;
     }
 
     /* Compatibility Mode (tdf#131304)
@@ -1194,7 +1204,6 @@ void DocxExport::WriteSettings()
             }
             else if (rProp.Name == "DocumentProtection")
             {
-
                 uno::Sequence< beans::PropertyValue > rAttributeList;
                 rProp.Value >>= rAttributeList;
 
@@ -1202,6 +1211,8 @@ void DocxExport::WriteSettings()
                 {
                     sax_fastparser::FastAttributeList* pAttributeList = sax_fastparser::FastSerializerHelper::createAttrList();
                     bool bIsProtectionTrackChanges = false;
+                    // if grabbag protection is not enforced, allow Writer protection to override
+                    bool bEnforced = false;
                     for (const auto& rAttribute : std::as_const(rAttributeList))
                     {
                         static DocxStringTokenMap const aTokens[] =
@@ -1225,12 +1236,17 @@ void DocxExport::WriteSettings()
                             pAttributeList->add(FSNS(XML_w, nToken), sValue.toUtf8());
                             if ( nToken == XML_edit && sValue == "trackedChanges" )
                                 bIsProtectionTrackChanges = true;
+                            else if ( nToken == XML_enforcement )
+                                bEnforced = sValue.toBoolean();
                         }
                     }
 
                     // we have document protection from input DOCX file
                     // and in the case of change tracking protection, we didn't modify it
                     hasProtectionProperties = !bIsProtectionTrackChanges || bHasDummyRedlineProtectionKey;
+                    // use grabbag if still valid/enforced
+                    // or leave as an un-enforced suggestion if Writer doesn't want to set any enforcement
+                    hasProtectionProperties &= bEnforced || !bWriterWantsToProtect;
                     if ( hasProtectionProperties )
                     {
                         sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
@@ -1264,8 +1280,7 @@ void DocxExport::WriteSettings()
     {
         // Protect form - highest priority
         // Section-specific write protection
-        if (m_pDoc->getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_FORM) ||
-            m_pSections->DocumentIsProtected())
+        if ( bWriterWantsToProtectForm )
         {
             // we have form protection from Writer or from input ODT file
 
@@ -1274,7 +1289,7 @@ void DocxExport::WriteSettings()
                 FSNS(XML_w, XML_enforcement), "true");
         }
         // Protect Change Tracking - next priority
-        else if ( bHasRedlineProtectionKey && !bHasDummyRedlineProtectionKey )
+        else if ( bWriterWantsToProtectRedline )
         {
             // we have change tracking protection from Writer or from input ODT file
 


More information about the Libreoffice-commits mailing list