sc/source/filter/excel/excdoc.cxx |   33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

New commits:
commit f138cc8fff47c4bb4fc361698bc788dd360a7dd7
Author:     Tünde Tóth <toth.tu...@nisz.hu>
AuthorDate: Mon Oct 11 09:35:35 2021 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Oct 20 17:14:00 2021 +0200

    tdf#144996 XLSX export: keep permission for editing on save
    
    The password for editing lost on Save, breaking the workflow
    with newer MSO versions, i.e. after saving, it was possible
    to modify the file on its original path without password.
    
    Manual test:
    
    - Open an XLSX document with permission for
    editing e.g. created with Excel 2019 or newer;
    
    - Choose Edit->Edit Mode and give the permission for edit
      with the requested password;
    
    - modify the file, and save it with File->Save. The file
      workbook.xml keeps <fileSharing> with the original hashValue,
      saltValue and spinCount.
    
    Change-Id: I6ad96a474c8e0ede7d5994a54f017d565e0c0f94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123435
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sc/source/filter/excel/excdoc.cxx 
b/sc/source/filter/excel/excdoc.cxx
index 1f43caaf73f9..6b02457f70f6 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -806,11 +806,27 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
     uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 
pDocShell->GetModel(), uno::UNO_QUERY_THROW );
     uno::Reference<document::XDocumentProperties> xDocProps = 
xDPS->getDocumentProperties();
 
-    sal_uInt32 nWriteProtHash = pDocShell->GetModifyPasswordHash();
     OUString sUserName = GetUserName();
-    bool bHasPassword = nWriteProtHash && !sUserName.isEmpty();
-    rStrm.exportDocumentProperties(xDocProps,
-                                   pDocShell->IsSecurityOptOpenReadOnly() && 
!bHasPassword);
+    sal_uInt32 nWriteProtHash = pDocShell->GetModifyPasswordHash();
+    bool bHasPasswordHash = nWriteProtHash && !sUserName.isEmpty();
+    const uno::Sequence<beans::PropertyValue> aInfo = 
pDocShell->GetModifyPasswordInfo();
+    OUString sAlgorithm, sSalt, sHash;
+    sal_Int32 nCount = 0;
+    for (const auto& prop : aInfo)
+    {
+        if (prop.Name == "algorithm-name")
+            prop.Value >>= sAlgorithm;
+        else if (prop.Name == "salt")
+            prop.Value >>= sSalt;
+        else if (prop.Name == "iteration-count")
+            prop.Value >>= nCount;
+        else if (prop.Name == "hash")
+            prop.Value >>= sHash;
+    }
+    bool bHasPasswordInfo
+        = sAlgorithm != "PBKDF2" && !sSalt.isEmpty() && !sHash.isEmpty() && 
!sUserName.isEmpty();
+    rStrm.exportDocumentProperties(xDocProps, 
pDocShell->IsSecurityOptOpenReadOnly()
+                                                  && !bHasPasswordHash && 
!bHasPasswordInfo);
     rStrm.exportCustomFragments();
 
     sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
@@ -825,10 +841,17 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
             // OOXTODO: XML_rupBuild
     );
 
-    if (bHasPassword)
+    if (bHasPasswordHash)
         rWorkbook->singleElement(XML_fileSharing,
                 XML_userName, sUserName,
                 XML_reservationPassword, OString::number(nWriteProtHash, 
16).getStr());
+    else if (bHasPasswordInfo)
+        rWorkbook->singleElement(XML_fileSharing,
+                XML_userName, sUserName,
+                XML_algorithmName, sAlgorithm.toUtf8().getStr(),
+                XML_hashValue, sHash.toUtf8().getStr(),
+                XML_saltValue, sSalt.toUtf8().getStr(),
+                XML_spinCount, OString::number(nCount).getStr());
 
     if( !maTableList.IsEmpty() )
     {

Reply via email to