summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2022-05-16 16:05:59 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2022-05-18 16:47:51 +0200
commit17c8917e6818f160b7965466851fabb351e3459a (patch)
treed3d85e5d2477290e17909640bf3bb4623d9380b0
parent270e8967a720166205263cf695aedb00f8f7ecd9 (diff)
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 <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134493 Tested-by: Jenkins
-rw-r--r--framework/source/services/autorecovery.cxx17
-rw-r--r--sc/qa/uitest/calc_tests9/tdf123877.py52
-rw-r--r--sc/qa/uitest/data/tdf123877.xlsxbin0 -> 15892 bytes
-rw-r--r--sc/source/ui/docshell/docsh.cxx14
4 files changed, 82 insertions, 1 deletions
diff --git a/framework/source/services/autorecovery.cxx b/framework/source/services/autorecovery.cxx
index ebcae2a0862b..69b729f29076 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>
@@ -84,6 +85,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>
@@ -3051,10 +3053,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
--- /dev/null
+++ b/sc/qa/uitest/data/tdf123877.xlsx
Binary files differ
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 4a13484c82cf..19992e3641d5 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -136,6 +136,9 @@
#include <memory>
#include <vector>
+#include <svtools/sfxecode.hxx>
+#include <unotools/pathoptions.hxx>
+
using namespace com::sun::star;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::lang::XMultiServiceFactory;
@@ -1789,6 +1792,17 @@ bool ScDocShell::SaveAs( SfxMedium& rMedium )
bNeedsRehash = ScPassHashHelper::needsPassHashRegen(m_aDocument, 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))