diff options
author | László Németh <nemeth@numbertext.org> | 2022-05-16 16:05:59 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2022-05-18 16:47:51 +0200 |
commit | 17c8917e6818f160b7965466851fabb351e3459a (patch) | |
tree | d3d85e5d2477290e17909640bf3bb4623d9380b0 | |
parent | 270e8967a720166205263cf695aedb00f8f7ecd9 (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.cxx | 17 | ||||
-rw-r--r-- | sc/qa/uitest/calc_tests9/tdf123877.py | 52 | ||||
-rw-r--r-- | sc/qa/uitest/data/tdf123877.xlsx | bin | 0 -> 15892 bytes | |||
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 14 |
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 Binary files differnew file mode 100644 index 000000000000..64167ca474fb --- /dev/null +++ b/sc/qa/uitest/data/tdf123877.xlsx 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)) |