framework/source/services/autorecovery.cxx |   17 ++++++++-
 sc/qa/uitest/calc_tests9/tdf123877.py      |   52 +++++++++++++++++++++++++++++
 sc/qa/uitest/data/tdf123877.xlsx           |binary
 sc/source/ui/docshell/docsh.cxx            |   13 +++++++
 4 files changed, 81 insertions(+), 1 deletion(-)

New commits:
commit 6af4c1d097dfba897e305a1e57d1e920f36ce264
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Mon May 16 16:05:59 2022 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Tue May 17 15:36:00 2022 +0200

    tdf#123877 sc XLSX: don't freeze during saving recovery
    
    file by asking password re-typing unstoppably. Instead
    of this, skip recovery file saving, if the document
    contains password hashes which haven't been supported
    by the "calc8" filter of the recovery file (which
    triggered the "Re-type password" dialog).
    
    Solved problems:
    
    – Asking for passwords during a non-interactive
      background process.
    
    – A single Cancel didn't close the "Re-type password" dialog
      window, only pressing three times at least (according to the
      value of RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL), but
      waiting for the password for a while could result a
      frozen "Re-type password" dialog, where only retyping or
      removing the password(s) were the escape routes.
    
    – Re-typing the password required the password (but modifying
      the original document doesn't require this).
    
    – Removing the password resulted in loss of the protection
      after saving the original XLSX document.
    
    Add a UI test to keep the "Re-type password" dialog during Save As.
    
    Note: because of the regression reported in tdf#145757, it needs
    to wait 10 min for saving the recovery file, yet, despite the
    changed time in Tools->Options->Load/Save->General.
    
    Change-Id: Icc6ee4d67048cdf15ab75ef8e2ee8f1709cdd4c2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134409
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/framework/source/services/autorecovery.cxx 
b/framework/source/services/autorecovery.cxx
index e3321773256f..ffc426a21d19 100644
--- a/framework/source/services/autorecovery.cxx
+++ b/framework/source/services/autorecovery.cxx
@@ -55,6 +55,7 @@
 #include <com/sun/star/util/XCloseable.hpp>
 #include <com/sun/star/awt/XWindow2.hpp>
 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
 #include <com/sun/star/lang/XTypeProvider.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
@@ -86,6 +87,7 @@
 #include <tools/diagnose_ex.h>
 #include <unotools/tempfile.hxx>
 #include <ucbhelper/content.hxx>
+#include <svtools/sfxecode.hxx>
 
 #include <vcl/weld.hxx>
 #include <osl/file.hxx>
@@ -3053,10 +3055,23 @@ void AutoRecovery::implts_saveOneDoc(const OUString&
             nRetry = 0;
 #endif // TRIGGER_FULL_DISC_CHECK
         }
-        catch(const css::uno::Exception&)
+        catch(const css::uno::Exception& rException)
         {
             bError = true;
 
+            // skip saving XLSX with protected sheets, if their passwords 
haven't supported yet
+            if ( rException.Message.startsWith("SfxBaseModel::impl_store") )
+            {
+                const css::task::ErrorCodeIOException& pErrorCodeIOException =
+                    static_cast<const 
css::task::ErrorCodeIOException&>(rException);
+                if ( static_cast<ErrCode>(pErrorCodeIOException.ErrCode) == 
ERRCODE_SFX_WRONGPASSWORD )
+                {
+                    // stop and remove the bad temporary file, instead of 
filling the disk with them
+                    bError = false;
+                    break;
+                }
+            }
+
             // a) FULL DISC seems to be the problem behind                     
         => show error and retry it forever (e.g. retry=300)
             // b) unknown problem (may be locking problem)                     
         => reset RETRY value to more useful value(!) (e.g. retry=3)
             // c) unknown problem (may be locking problem) + 1..2 repeating 
operations  => throw the original exception to force generation of a stacktrace 
!
diff --git a/sc/qa/uitest/calc_tests9/tdf123877.py 
b/sc/qa/uitest/calc_tests9/tdf123877.py
new file mode 100644
index 000000000000..5162f88d9b78
--- /dev/null
+++ b/sc/qa/uitest/calc_tests9/tdf123877.py
@@ -0,0 +1,52 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from uitest.framework import UITestCase
+from uitest.uihelper.calc import enter_text_to_cell
+from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file
+from uitest.uihelper.common import select_by_text
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from org.libreoffice.unotest import systemPathToFileUrl
+from tempfile import TemporaryDirectory
+import os.path
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.calc.document import get_cell_by_position
+
+
+class tdf123877(UITestCase):
+
+    def test_tdf123877(self):
+
+        xFilePath = get_url_for_data_file("tdf123877.xlsx")
+
+        with self.ui_test.load_file(xFilePath) as document:
+
+            # Save the XLSX document as ODS with a sheet protected with an 
unsupported hash format
+            with self.ui_test.execute_dialog_through_command(".uno:SaveAs", 
close_button="") as xSaveDialog:
+                xFileName = xSaveDialog.getChild("file_name")
+                xFileName.executeAction("TYPE", 
mkPropertyValues({"KEYCODE":"CTRL+A"}))
+                xFileName.executeAction("TYPE", 
mkPropertyValues({"KEYCODE":"BACKSPACE"}))
+                xFileName.executeAction("TYPE", mkPropertyValues({"TEXT": 
xFilePath}))
+                xFileTypeCombo = xSaveDialog.getChild("file_type")
+                select_by_text(xFileTypeCombo, "ODF Spreadsheet (.ods)")
+
+                xOpen = xSaveDialog.getChild("open")
+
+                with self.ui_test.execute_dialog_through_action(xOpen, 
"CLICK", close_button="") as xRetypePasswordDialog:
+                    # hash error dialog is still displayed (only disabled for 
the recovery file)
+                    xCancel = xRetypePasswordDialog.getChild("cancel")
+
+                    with self.ui_test.execute_dialog_through_action(xCancel, 
"CLICK", close_button="ok"):
+                    # Write error dialog is displayed
+                        pass
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/qa/uitest/data/tdf123877.xlsx b/sc/qa/uitest/data/tdf123877.xlsx
new file mode 100644
index 000000000000..64167ca474fb
Binary files /dev/null and b/sc/qa/uitest/data/tdf123877.xlsx differ
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 4a55665d0f5a..827958de5858 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -138,6 +138,8 @@
 #include <vector>
 
 #include <comphelper/lok.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/pathoptions.hxx>
 
 using namespace com::sun::star;
 using ::com::sun::star::uno::Reference;
@@ -1809,6 +1811,17 @@ bool ScDocShell::SaveAs( SfxMedium& rMedium )
         bNeedsRehash = ScPassHashHelper::needsPassHashRegen(*m_pDocument, 
PASSHASH_SHA256);
     }
 
+    // skip saving recovery file instead of showing re-type password dialog 
window
+    if ( bNeedsRehash && rMedium.GetFilter()->GetFilterName() == "calc8" &&
+            // it seems, utl::MediaDescriptor::PROP_AUTOSAVEEVENT is true at 
Save As, too,
+            // so check the backup path
+            rMedium.GetName().startsWith( SvtPathOptions().GetBackupPath() ) )
+    {
+        SAL_WARN("sc.filter", "Should re-type password for own format, won't 
export recovery file");
+        rMedium.SetError(ERRCODE_SFX_WRONGPASSWORD);
+        return false;
+    }
+
     if (pViewShell && bNeedsRehash)
     {
         if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_SHA1))

Reply via email to