summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-02-22 21:07:34 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2021-02-23 12:25:06 +0100
commitd0911a2070c73e90251591b1e853947ca2f22a42 (patch)
tree59436de79e7eb91783f72559d08541a4353620ad
parent8cd13e3c2e8dc096b747e01a59cda146b0da908a (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>
-rw-r--r--sfx2/CppunitTest_sfx2_doc.mk1
-rw-r--r--sfx2/qa/cppunit/doc.cxx31
-rw-r--r--sfx2/source/doc/docfile.cxx17
3 files changed, 39 insertions, 10 deletions
diff --git a/sfx2/CppunitTest_sfx2_doc.mk b/sfx2/CppunitTest_sfx2_doc.mk
index 02b06dfd1b14..bf181c2325d6 100644
--- a/sfx2/CppunitTest_sfx2_doc.mk
+++ b/sfx2/CppunitTest_sfx2_doc.mk
@@ -27,6 +27,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sfx2_doc, \
unotest \
sfx \
svl \
+ utl \
))
$(eval $(call gb_CppunitTest_use_sdk_api,sfx2_doc))
diff --git a/sfx2/qa/cppunit/doc.cxx b/sfx2/qa/cppunit/doc.cxx
index 01e8fd7f2000..058bf4788d67 100644
--- a/sfx2/qa/cppunit/doc.cxx
+++ b/sfx2/qa/cppunit/doc.cxx
@@ -17,6 +17,9 @@
#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;
@@ -74,6 +77,34 @@ CPPUNIT_TEST_FIXTURE(Test, testNoGrabBagShape)
// which was not caught later, resulting in a crash.
pObjectShell->GetSignPDFCertificate();
}
+
+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();
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 7a1bf5a7f2c9..59865fb2b8eb 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -3620,7 +3620,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;
@@ -3631,15 +3631,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)
@@ -3663,7 +3660,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();
@@ -3759,7 +3756,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();