summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-02-22 21:07:34 +0100
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2021-03-02 19:30:06 +0100
commit55b7490decf9a22e609a4bcad717e20664da278c (patch)
tree35784210a5984ee26bcf8265d4694617d163b3f2
parentf78648cdb3672972c47f59256305623d8ff5f444 (diff)
tdf#139039 sfx2 store: fix export to PDF when dir name is URL-encoded
Regression from commit 5259ab8104cfba60c40748ed0cd59d93df038c5b (sfx2 store: create temp files next to local files, 2018-01-08), the problem was that the directory hosting the input ODT file was called "Bugzilla%C3%BF" (URL-encoded from "ÿ"), we got this as "Bugzilla%25C3%25BF" (encoded from directory name), but we forgot to decode it before passing this URL to the utl::TempFile ctor as a parent directory, which resulted in failing to save as PDF, and crashing on DOCX export. Note that in practice this only caused a problem on Windows. (cherry picked from commit aaf7fe0326b3be088a5440525363317fb3d0f158) Change-Id: I5fc8a356b63efc2f16405a14ee59a061b52c5205 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111372 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111747 (cherry picked from commit 55a6b24e0809246ec5700dcd76856df9d8348e36) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111775 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r--sfx2/CppunitTest_sfx2_doc.mk46
-rw-r--r--sfx2/Module_sfx2.mk1
-rw-r--r--sfx2/qa/cppunit/doc.cxx86
-rw-r--r--sfx2/source/doc/docfile.cxx17
4 files changed, 140 insertions, 10 deletions
diff --git a/sfx2/CppunitTest_sfx2_doc.mk b/sfx2/CppunitTest_sfx2_doc.mk
new file mode 100644
index 000000000000..bf181c2325d6
--- /dev/null
+++ b/sfx2/CppunitTest_sfx2_doc.mk
@@ -0,0 +1,46 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# 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/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sfx2_doc))
+
+$(eval $(call gb_CppunitTest_use_externals,sfx2_doc,\
+ boost_headers \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sfx2_doc, \
+ sfx2/qa/cppunit/doc \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sfx2_doc, \
+ comphelper \
+ cppu \
+ sal \
+ test \
+ unotest \
+ sfx \
+ svl \
+ utl \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sfx2_doc))
+
+$(eval $(call gb_CppunitTest_use_ure,sfx2_doc))
+$(eval $(call gb_CppunitTest_use_vcl,sfx2_doc))
+
+$(eval $(call gb_CppunitTest_use_rdb,sfx2_doc,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sfx2_doc,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sfx2_doc))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sfx2/Module_sfx2.mk b/sfx2/Module_sfx2.mk
index 8ebe54cef9c7..a0158b52ca09 100644
--- a/sfx2/Module_sfx2.mk
+++ b/sfx2/Module_sfx2.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_Module_add_check_targets,sfx2,\
CppunitTest_sfx2_misc \
CppunitTest_sfx2_controlleritem \
CppunitTest_sfx2_classification \
+ CppunitTest_sfx2_doc \
))
$(eval $(call gb_Module_add_subsequentcheck_targets,sfx2,\
diff --git a/sfx2/qa/cppunit/doc.cxx b/sfx2/qa/cppunit/doc.cxx
new file mode 100644
index 000000000000..8f2587ec95c7
--- /dev/null
+++ b/sfx2/qa/cppunit/doc.cxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/sfxbasemodel.hxx>
+#include <unotools/tempfile.hxx>
+#include <sfx2/docfile.hxx>
+#include <osl/file.hxx>
+
+using namespace com::sun::star;
+
+namespace
+{
+/// Covers sfx2/source/doc/ fixes.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTempFilePath)
+{
+ // Create a test file in a directory that contains the URL-encoded "testÿ" string.
+ getComponent() = loadFromDesktop("private:factory/swriter");
+ auto pBaseModel = dynamic_cast<SfxBaseModel*>(getComponent().get());
+ CPPUNIT_ASSERT(pBaseModel);
+ OUString aTargetDir
+ = m_directories.getURLFromWorkdir(u"CppunitTest/sfx2_doc.test.user/test%25C3%25Bf");
+ osl::Directory::create(aTargetDir);
+ OUString aTargetFile = aTargetDir + "/test.odt";
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "FilterName", OUString("writer8")) };
+ pBaseModel->storeAsURL(aTargetFile, aArgs);
+ getComponent()->dispose();
+
+ // Load it and export to PDF.
+ getComponent() = loadFromDesktop(aTargetFile);
+ pBaseModel = dynamic_cast<SfxBaseModel*>(getComponent().get());
+ OUString aPdfTarget = aTargetDir + "/test.pdf";
+ css::uno::Sequence<css::beans::PropertyValue> aPdfArgs{ comphelper::makePropertyValue(
+ "FilterName", OUString("writer_pdf_Export")) };
+ // Without the accompanying fix in place, this test would have failed on Windows with:
+ // An uncaught exception of type com.sun.star.io.IOException
+ // because we first tried to create a temp file next to test.odt in a directory named
+ // "test%25C3%25Bf" instead of a directory named "test%C3%Bf".
+ pBaseModel->storeToURL(aPdfTarget, aPdfArgs);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 57a85ffe16a8..01e94c037e8c 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3616,7 +3616,7 @@ bool SfxMedium::SetWritableForUserOnly( const OUString& aURL )
namespace
{
/// Get the parent directory of a temporary file for output purposes.
-OUString GetLogicBase(std::unique_ptr<SfxMedium_Impl> const & pImpl)
+OUString GetLogicBase(const INetURLObject& rURL, std::unique_ptr<SfxMedium_Impl> const & pImpl)
{
OUString aLogicBase;
@@ -3627,15 +3627,12 @@ OUString GetLogicBase(std::unique_ptr<SfxMedium_Impl> const & pImpl)
(void) pImpl;
#else
- if (comphelper::isFileUrl(pImpl->m_aLogicName) && !pImpl->m_pInStream)
+ if (rURL.GetProtocol() == INetProtocol::File && !pImpl->m_pInStream)
{
// Try to create the temp file in the same directory when storing.
- sal_Int32 nOffset = pImpl->m_aLogicName.lastIndexOf("/");
- if (nOffset != -1)
- aLogicBase = pImpl->m_aLogicName.copy(0, nOffset);
- if (aLogicBase == "file://")
- // Doesn't make sense.
- aLogicBase.clear();
+ INetURLObject aURL(rURL);
+ aURL.removeSegment();
+ aLogicBase = aURL.GetMainURL(INetURLObject::DecodeMechanism::WithCharset);
}
if (pImpl->m_bHasEmbeddedObjects)
@@ -3659,7 +3656,7 @@ void SfxMedium::CreateTempFile( bool bReplace )
pImpl->m_aName.clear();
}
- OUString aLogicBase = GetLogicBase(pImpl);
+ OUString aLogicBase = GetLogicBase(GetURLObject(), pImpl);
pImpl->pTempFile.reset( new ::utl::TempFile(aLogicBase.isEmpty() ? nullptr : &aLogicBase) );
pImpl->pTempFile->EnableKillingFile();
pImpl->m_aName = pImpl->pTempFile->GetFileName();
@@ -3755,7 +3752,7 @@ void SfxMedium::CreateTempFileNoCopy()
// this call always replaces the existing temporary file
pImpl->pTempFile.reset();
- OUString aLogicBase = GetLogicBase(pImpl);
+ OUString aLogicBase = GetLogicBase(GetURLObject(), pImpl);
pImpl->pTempFile.reset( new ::utl::TempFile(aLogicBase.isEmpty() ? nullptr : &aLogicBase) );
pImpl->pTempFile->EnableKillingFile();
pImpl->m_aName = pImpl->pTempFile->GetFileName();